diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:57 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 16:48:57 +0000 |
commit | 9508a382f8a9f241dab097d921b6d290c1c3a776 (patch) | |
tree | fa456480bae7040c3f971a70b390f2d091c680b5 /hw/xfree86/os-support | |
parent | ded6147bfb5d75ff1e67c858040a628b61bc17d1 (diff) |
Initial revision
Diffstat (limited to 'hw/xfree86/os-support')
100 files changed, 28222 insertions, 0 deletions
diff --git a/hw/xfree86/os-support/bsd/alpha_video.c b/hw/xfree86/os-support/bsd/alpha_video.c new file mode 100644 index 000000000..d3aa25961 --- /dev/null +++ b/hw/xfree86/os-support/bsd/alpha_video.c @@ -0,0 +1,709 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/alpha_video.c,v 1.2.2.1 2003/05/09 02:30:43 dawes Exp $ */ +/* + * Copyright 1992 by Rich Murphey <Rich@Rice.edu> + * 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 Rich Murphey and David Wexelblat + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. Rich Murphey and + * David Wexelblat make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RICH MURPHEY 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. + * + */ + +/* $XConsortium: bsd_video.c /main/10 1996/10/25 11:37:57 kaleb $ */ + +#include "X.h" +#include "xf86.h" +#include "xf86Priv.h" + +#include <sys/param.h> +#ifndef __NetBSD__ +# include <sys/sysctl.h> +# ifdef __FreeBSD__ +# include <machine/sysarch.h> +# endif +# else +# include <machine/sysarch.h> +#endif + +#include "xf86Axp.h" + +#include "xf86_OSlib.h" +#include "xf86OSpriv.h" + +#if defined(__NetBSD__) && !defined(MAP_FILE) +#define MAP_FLAGS MAP_SHARED +#else +#define MAP_FLAGS (MAP_FILE | MAP_SHARED) +#endif + +#ifndef MAP_FAILED +#define MAP_FAILED ((caddr_t)-1) +#endif + +axpDevice bsdGetAXP(void); + +#ifndef __NetBSD__ +extern unsigned long dense_base(void); + +static int axpSystem = -1; +static unsigned long hae_thresh; +static unsigned long hae_mask; +static unsigned long bus_base; +static unsigned long sparse_size; + +static unsigned long +memory_base(void) +{ + static unsigned long base = 0; + + if (base == 0) { + size_t len = sizeof(base); + int error; +#ifdef __OpenBSD__ + int mib[3]; + + mib[0] = CTL_MACHDEP; + mib[1] = CPU_CHIPSET; + mib[2] = CPU_CHIPSET_MEM; + + if ((error = sysctl(mib, 3, &base, &len, NULL, 0)) < 0) +#else + if ((error = sysctlbyname("hw.chipset.memory", &base, &len, + 0, 0)) < 0) +#endif + FatalError("xf86MapVidMem: can't find memory\n"); + } + + return base; +} + +static int +has_bwx(void) +{ + static int bwx = 0; + size_t len = sizeof(bwx); + int error; +#ifdef __OpenBSD__ + int mib[3]; + + mib[0] = CTL_MACHDEP; + mib[1] = CPU_CHIPSET; + mib[2] = CPU_CHIPSET_BWX; + + if ((error = sysctl(mib, 3, &bwx, &len, NULL, 0)) < 0) + return FALSE; + else + return bwx; +#else + if ((error = sysctlbyname("hw.chipset.bwx", &bwx, &len, 0, 0)) < 0) + return FALSE; + else + return bwx; +#endif +} +#else /* __NetBSD__ */ +static struct alpha_bus_window *abw; +static int abw_count = -1; + +static void +init_abw() +{ + if (abw_count < 0) { + abw_count = alpha_bus_getwindows(ALPHA_BUS_TYPE_PCI_MEM, &abw); + if (abw_count <= 0) + FatalError("init_abw: alpha_bus_getwindows failed\n"); + } +} + +static int +has_bwx(void) +{ + if (abw_count < 0) + init_abw(); + + xf86Msg(X_INFO, "has_bwx = %d\n", + abw[0].abw_abst.abst_flags & ABST_BWX ? 1 : 0); /* XXXX */ + return abw[0].abw_abst.abst_flags & ABST_BWX; +} + +static unsigned long +dense_base() +{ + if (abw_count < 0) + init_abw(); + + /* XXX check abst_flags for ABST_DENSE just to be safe? */ + xf86Msg(X_INFO, "dense base = %#lx\n", + abw[0].abw_abst.abst_sys_start); /* XXXX */ + return abw[0].abw_abst.abst_sys_start; +} + +static unsigned long +memory_base() +{ + if (abw_count < 0) + init_abw(); + + if (abw_count > 0) { + xf86Msg(X_INFO, "memory base = %#lx\n", + abw[1].abw_abst.abst_sys_start); /* XXXX */ + return abw[1].abw_abst.abst_sys_start; + } else { + xf86Msg(X_INFO, "no memory base\n"); /* XXXX */ + return 0; + } +} +#endif /* __NetBSD__ */ + +#define BUS_BASE dense_base() +#define BUS_BASE_BWX memory_base() + +/***************************************************************************/ +/* Video Memory Mapping section */ +/***************************************************************************/ + +#ifdef __OpenBSD__ +#define SYSCTL_MSG "\tCheck that you have set 'machdep.allowaperture=1'\n"\ + "\tin /etc/sysctl.conf and reboot your machine\n" \ + "\trefer to xf86(4) for details" +#endif + +static Bool useDevMem = FALSE; +static int devMemFd = -1; + +#ifdef HAS_APERTURE_DRV +#define DEV_APERTURE "/dev/xf86" +#endif +#define DEV_MEM "/dev/mem" + +static pointer mapVidMem(int, unsigned long, unsigned long, int); +static void unmapVidMem(int, pointer, unsigned long); +static pointer mapVidMemSparse(int, unsigned long, unsigned long, int); +static void unmapVidMemSparse(int, pointer, unsigned long); + +/* + * Check if /dev/mem can be mmap'd. If it can't print a warning when + * "warn" is TRUE. + */ +static void +checkDevMem(Bool warn) +{ + static Bool devMemChecked = FALSE; + int fd; + pointer base; + + if (devMemChecked) + return; + devMemChecked = TRUE; + +#ifdef HAS_APERTURE_DRV + /* Try the aperture driver first */ + if ((fd = open(DEV_APERTURE, O_RDWR)) >= 0) { + /* Try to map a page at the VGA address */ + base = mmap((caddr_t)0, 4096, PROT_READ|PROT_WRITE, + MAP_FLAGS, fd, (off_t)0xA0000 + BUS_BASE); + + if (base != MAP_FAILED) { + munmap((caddr_t)base, 4096); + devMemFd = fd; + useDevMem = TRUE; + xf86Msg(X_INFO, "checkDevMem: using aperture driver %s\n", + DEV_APERTURE); + return; + } else { + if (warn) { + xf86Msg(X_WARNING, "checkDevMem: failed to mmap %s (%s)\n", + DEV_APERTURE, strerror(errno)); + } + } + } +#endif + if ((fd = open(DEV_MEM, O_RDWR)) >= 0) { + /* Try to map a page at the VGA address */ + base = mmap((caddr_t)0, 4096, PROT_READ|PROT_WRITE, + MAP_FLAGS, fd, (off_t)0xA0000 + BUS_BASE); + + if (base != MAP_FAILED) { + munmap((caddr_t)base, 4096); + devMemFd = fd; + useDevMem = TRUE; + return; + } else { + if (warn) { + xf86Msg(X_WARNING, "checkDevMem: failed to mmap %s (%s)\n", + DEV_MEM, strerror(errno)); + } + } + } + if (warn) { +#ifndef HAS_APERTURE_DRV + xf86Msg(X_WARNING, "checkDevMem: failed to open/mmap %s (%s)\n", + DEV_MEM, strerror(errno)); +#else +#ifndef __OpenBSD__ + xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n" + "\t(%s)\n", DEV_APERTURE, DEV_MEM, strerror(errno)); +#else /* __OpenBSD__ */ + xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n" + "\t(%s)\n%s", DEV_APERTURE, DEV_MEM, strerror(errno), + SYSCTL_MSG); +#endif /* __OpenBSD__ */ +#endif + xf86ErrorF("\tlinear framebuffer access unavailable\n"); + } + useDevMem = FALSE; + return; +} + +void +xf86OSInitVidMem(VidMemInfoPtr pVidMem) +{ + checkDevMem(TRUE); + pVidMem->linearSupported = useDevMem; + + if (has_bwx()) { + xf86Msg(X_PROBED,"Machine type has 8/16 bit access\n"); + pVidMem->mapMem = mapVidMem; + pVidMem->unmapMem = unmapVidMem; + } else { + xf86Msg(X_PROBED,"Machine needs sparse mapping\n"); + pVidMem->mapMem = mapVidMemSparse; + pVidMem->unmapMem = unmapVidMemSparse; + if (axpSystem == -1) + axpSystem = bsdGetAXP(); + hae_thresh = xf86AXPParams[axpSystem].hae_thresh; + hae_mask = xf86AXPParams[axpSystem].hae_mask; + sparse_size = xf86AXPParams[axpSystem].size; + } + pVidMem->initialised = TRUE; +} + +static pointer +mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags) +{ + pointer base; + + checkDevMem(FALSE); + Base = Base & ((1L<<32) - 1); + + if (useDevMem) + { + if (devMemFd < 0) + { + FatalError("xf86MapVidMem: failed to open %s (%s)\n", + DEV_MEM, strerror(errno)); + } + base = mmap((caddr_t)0, Size, PROT_READ|PROT_WRITE, + MAP_FLAGS, devMemFd, (off_t)Base + BUS_BASE_BWX); + if (base == MAP_FAILED) + { + FatalError("%s: could not mmap %s [s=%x,a=%x] (%s)\n", + "xf86MapVidMem", DEV_MEM, Size, Base, + strerror(errno)); + } + return(base); + } + + /* else, mmap /dev/vga */ + if ((unsigned long)Base < 0xA0000 || (unsigned long)Base >= 0xC0000) + { + FatalError("%s: Address 0x%x outside allowable range\n", + "xf86MapVidMem", Base); + } + base = mmap(0, Size, PROT_READ|PROT_WRITE, MAP_FLAGS, + xf86Info.screenFd, + (unsigned long)Base + BUS_BASE); + if (base == MAP_FAILED) + { + FatalError("xf86MapVidMem: Could not mmap /dev/vga (%s)\n", + strerror(errno)); + } + return(base); +} + +static void +unmapVidMem(int ScreenNum, pointer Base, unsigned long Size) +{ + munmap((caddr_t)Base, Size); +} + +/* + * Read BIOS via mmap()ing DEV_MEM + */ + +int +xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf, + int Len) +{ + unsigned char *ptr; + int psize; + int mlen; + + checkDevMem(TRUE); + if (devMemFd == -1) { + return(-1); + } + + psize = xf86getpagesize(); + Offset += Base & (psize - 1); + Base &= ~(psize - 1); + mlen = (Offset + Len + psize - 1) & ~(psize - 1); + ptr = (unsigned char *)mmap((caddr_t)0, mlen, PROT_READ, + MAP_SHARED, devMemFd, (off_t)Base+BUS_BASE); + if ((long)ptr == -1) + { + xf86Msg(X_WARNING, + "xf86ReadBIOS: %s mmap[s=%x,a=%x,o=%x] failed (%s)\n", + DEV_MEM, Len, Base, Offset, strerror(errno)); + return(-1); + } +#ifdef DEBUG + xf86MsgVerb(X_INFO, 3, "xf86ReadBIOS: BIOS at 0x%08x has signature 0x%04x\n", + Base, ptr[0] | (ptr[1] << 8)); +#endif + (void)memcpy(Buf, (void *)(ptr + Offset), Len); + (void)munmap((caddr_t)ptr, mlen); +#ifdef DEBUG + xf86MsgVerb(X_INFO, 3, "xf86ReadBIOS(%x, %x, Buf, %x)" + "-> %02x %02x %02x %02x...\n", + Base, Offset, Len, Buf[0], Buf[1], Buf[2], Buf[3]); +#endif + return(Len); +} + + +#if defined(__FreeBSD__) || defined(__OpenBSD__) + +extern int ioperm(unsigned long from, unsigned long num, int on); + +void +xf86EnableIO() +{ + ioperm(0, 65536, TRUE); + return; +} + +void +xf86DisableIO() +{ + return; +} + +#endif /* __FreeBSD__ || __OpenBSD__ */ + +#ifdef USE_ALPHA_PIO + +void +xf86EnableIO() +{ + alpha_pci_io_enable(1); +} + +void +xf86DisableIO() +{ + alpha_pci_io_enable(0); +} + +#endif /* USE_ALPHA_PIO */ + +/***************************************************************************/ +/* Interrupt Handling section */ +/***************************************************************************/ + +Bool +xf86DisableInterrupts() +{ + + return(TRUE); +} + +void +xf86EnableInterrupts() +{ + return; +} + + +#define vuip volatile unsigned int * + +static unsigned long msb_set = 0; +static pointer memSBase = 0; +static pointer memBase = 0; + +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); + +#ifdef __FreeBSD__ +extern int sysarch(int, char *); +#endif + +struct parms { + u_int64_t hae; +}; + +static int +sethae(u_int64_t hae) +{ +#ifdef __FreeBSD__ +#ifndef ALPHA_SETHAE +#define ALPHA_SETHAE 0 +#endif + struct parms p; + p.hae = hae; + return (sysarch(ALPHA_SETHAE, (char *)&p)); +#endif +#ifdef __OpenBSD__ + return -1; +#endif +} + +static pointer +mapVidMemSparse(int ScreenNum, unsigned long Base, unsigned long Size, int flags) +{ + static Bool was_here = FALSE; + + if (!was_here) { + was_here = TRUE; + + checkDevMem(FALSE); + + xf86WriteMmio8 = writeSparse8; + xf86WriteMmio16 = writeSparse16; + xf86WriteMmio32 = writeSparse32; + xf86WriteMmioNB8 = writeSparseNB8; + xf86WriteMmioNB16 = writeSparseNB16; + xf86WriteMmioNB32 = writeSparseNB32; + xf86ReadMmio8 = readSparse8; + xf86ReadMmio16 = readSparse16; + xf86ReadMmio32 = readSparse32; + + memBase = mmap((caddr_t)0, 0x100000000, + PROT_READ | PROT_WRITE, + MAP_SHARED, devMemFd, + (off_t) BUS_BASE); + memSBase = mmap((caddr_t)0, 0x100000000, + PROT_READ | PROT_WRITE, + MAP_SHARED, devMemFd, + (off_t) BUS_BASE_BWX); + + if (memSBase == MAP_FAILED || memBase == MAP_FAILED) { + FatalError("xf86MapVidMem: Could not mmap framebuffer (%s)\n", + strerror(errno)); + } + } + return (pointer)((unsigned long)memBase + Base); +} + +static void +unmapVidMemSparse(int ScreenNum, pointer Base, unsigned long Size) +{ +} + +static int +readSparse8(pointer Base, register unsigned long Offset) +{ + register unsigned long result, shift; + register unsigned long msb; + + mem_barrier(); + Offset += (unsigned long)Base - (unsigned long)memBase; + shift = (Offset & 0x3) << 3; + if (Offset >= (hae_thresh)) { + msb = Offset & hae_mask; + Offset -= msb; + if (msb_set != msb) { + sethae(msb); + msb_set = msb; + } + } + + result = *(vuip) ((unsigned long)memSBase + (Offset << 5)); + result >>= shift; + return 0xffUL & result; +} + +static int +readSparse16(pointer Base, register unsigned long Offset) +{ + register unsigned long result, shift; + register unsigned long msb; + + mem_barrier(); + Offset += (unsigned long)Base - (unsigned long)memBase; + shift = (Offset & 0x2) << 3; + if (Offset >= (hae_thresh)) { + msb = Offset & hae_mask; + Offset -= msb; + if (msb_set != msb) { + sethae(msb); + msb_set = msb; + } + } + result = *(vuip)((unsigned long)memSBase+(Offset<<5)+(1<<(5-2))); + result >>= shift; + return 0xffffUL & result; +} + +static int +readSparse32(pointer Base, register unsigned long Offset) +{ + mem_barrier(); + return *(vuip)((unsigned long)Base+(Offset)); +} + +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 - (unsigned long)memBase; + if (Offset >= (hae_thresh)) { + msb = Offset & hae_mask; + Offset -= msb; + if (msb_set != msb) { + sethae(msb); + msb_set = msb; + } + } + *(vuip) ((unsigned long)memSBase + (Offset << 5)) = b * 0x01010101; +} + +static void +writeSparse16(int Value, pointer Base, register unsigned long Offset) +{ + register unsigned long msb; + register unsigned int w = Value & 0xffffU; + + write_mem_barrier(); + Offset += (unsigned long)Base - (unsigned long)memBase; + if (Offset >= (hae_thresh)) { + msb = Offset & hae_mask; + Offset -= msb; + if (msb_set != msb) { + sethae(msb); + msb_set = msb; + } + } + *(vuip)((unsigned long)memSBase+(Offset<<5)+(1<<(5-2))) = + w * 0x00010001; + +} + +static void +writeSparse32(int Value, pointer Base, register unsigned long Offset) +{ + 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 - (unsigned long)memBase; + if (Offset >= (hae_thresh)) { + msb = Offset & hae_mask; + Offset -= msb; + if (msb_set != msb) { + sethae(msb); + msb_set = msb; + } + } + *(vuip) ((unsigned long)memSBase + (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 - (unsigned long)memBase; + if (Offset >= (hae_thresh)) { + msb = Offset & hae_mask ; + Offset -= msb; + if (msb_set != msb) { + sethae(msb); + msb_set = msb; + } + } + *(vuip)((unsigned long)memSBase+(Offset<<5)+(1<<(5-2))) = + w * 0x00010001; +} + +static void +writeSparseNB32(int Value, pointer Base, register unsigned long Offset) +{ + *(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; + diff --git a/hw/xfree86/os-support/bsd/arm_video.c b/hw/xfree86/os-support/bsd/arm_video.c new file mode 100644 index 000000000..96abe2ea4 --- /dev/null +++ b/hw/xfree86/os-support/bsd/arm_video.c @@ -0,0 +1,677 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/arm_video.c,v 1.1 2002/08/06 13:08:38 herrb Exp $ */ +/* + * Copyright 1992 by Rich Murphey <Rich@Rice.edu> + * 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 Rich Murphey and David Wexelblat + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. Rich Murphey and + * David Wexelblat make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RICH MURPHEY 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. + * + */ + +/* + * The ARM32 code here carries the following copyright: + * + * Copyright 1997 + * Digital Equipment Corporation. All rights reserved. + * This software is furnished under license and may be used and copied only in + * accordance with the following terms and conditions. Subject to these + * conditions, you may download, copy, install, use, modify and distribute + * this software in source and/or binary form. No title or ownership is + * transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce and retain + * this copyright notice and list of conditions as they appear in the + * source file. + * + * 2) No right is granted to use any trade name, trademark, or logo of Digital + * Equipment Corporation. Neither the "Digital Equipment Corporation" + * name nor any trademark or logo of Digital Equipment Corporation may be + * used to endorse or promote products derived from this software without + * the prior written permission of Digital Equipment Corporation. + * + * 3) This software is provided "AS-IS" and any express or implied warranties, + * including but not limited to, any implied warranties of merchantability, + * fitness for a particular purpose, or non-infringement are disclaimed. + * In no event shall DIGITAL be liable for any damages whatsoever, and in + * particular, DIGITAL shall not be liable for special, indirect, + * consequential, or incidental damages or damages for lost profits, loss + * of revenue or loss of use, whether such damages arise in contract, + * negligence, tort, under statute, in equity, at law or otherwise, even + * if advised of the possibility of such damage. + * + */ + +/* $XConsortium: bsd_video.c /main/10 1996/10/25 11:37:57 kaleb $ */ + +#include "X.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "xf86OSpriv.h" + +#ifdef __arm32__ +#include "machine/devmap.h" +struct memAccess +{ + int ioctl; + struct map_info memInfo; + pointer regionVirtBase; + Bool Checked; + Bool OK; +}; + +static pointer xf86MapInfoMap(); +static void xf86MapInfoUnmap(); +static struct memAccess *checkMapInfo(); +extern int vgaPhysLinearBase; + +/* A memAccess structure is needed for each possible region */ +struct memAccess vgaMemInfo = { CONSOLE_GET_MEM_INFO, NULL, NULL, + FALSE, FALSE }; +struct memAccess linearMemInfo = { CONSOLE_GET_LINEAR_INFO, NULL, NULL, + FALSE, FALSE }; +struct memAccess ioMemInfo = { CONSOLE_GET_IO_INFO, NULL, NULL, + FALSE, FALSE }; +#endif /* __arm32__ */ + +#if defined(__NetBSD__) && !defined(MAP_FILE) +#define MAP_FLAGS MAP_SHARED +#else +#define MAP_FLAGS (MAP_FILE | MAP_SHARED) +#endif + +#ifndef MAP_FAILED +#define MAP_FAILED ((caddr_t)-1) +#endif + + +#define BUS_BASE 0L +#define BUS_BASE_BWX 0L + + +/***************************************************************************/ +/* Video Memory Mapping section */ +/***************************************************************************/ + +static Bool useDevMem = FALSE; +static int devMemFd = -1; + +#define DEV_MEM "/dev/mem" + +static pointer mapVidMem(int, unsigned long, unsigned long, int); +static void unmapVidMem(int, pointer, unsigned long); + +/* + * Check if /dev/mem can be mmap'd. If it can't print a warning when + * "warn" is TRUE. + */ +static void +checkDevMem(Bool warn) +{ + static Bool devMemChecked = FALSE; + int fd; + pointer base; + + if (devMemChecked) + return; + devMemChecked = TRUE; + + if ((fd = open(DEV_MEM, O_RDWR)) >= 0) + { + /* Try to map a page at the VGA address */ + base = mmap((caddr_t)0, 4096, PROT_READ|PROT_WRITE, + MAP_FLAGS, fd, (off_t)0xA0000 + BUS_BASE); + + if (base != MAP_FAILED) + { + munmap((caddr_t)base, 4096); + devMemFd = fd; + useDevMem = TRUE; + return; + } else { + /* This should not happen */ + if (warn) + { + xf86Msg(X_WARNING, "checkDevMem: failed to mmap %s (%s)\n", + DEV_MEM, strerror(errno)); + } + useDevMem = FALSE; + return; + } + } + if (warn) + { + xf86Msg(X_WARNING, "checkDevMem: failed to open %s (%s)\n", + DEV_MEM, strerror(errno)); + } + useDevMem = FALSE; + return; +} + +void +xf86OSInitVidMem(VidMemInfoPtr pVidMem) +{ + + checkDevMem(TRUE); + pVidMem->linearSupported = useDevMem; + pVidMem->mapMem = armMapVidMem; + pVidMem->unmapVidMem = armUnmapVidMem; + + pVidMem->initialised = TRUE; +} + +static pointer +mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags) +{ + pointer base; + + checkDevMem(FALSE); + + if (useDevMem) + { + if (devMemFd < 0) + { + FatalError("xf86MapVidMem: failed to open %s (%s)\n", + DEV_MEM, strerror(errno)); + } + base = mmap((caddr_t)0, Size, PROT_READ|PROT_WRITE, + MAP_FLAGS, devMemFd, (off_t)Base + BUS_BASE_BWX); + if (base == MAP_FAILED) + { + FatalError("%s: could not mmap %s [s=%x,a=%x] (%s)\n", + "xf86MapVidMem", DEV_MEM, Size, Base, + strerror(errno)); + } + return(base); + } + + /* else, mmap /dev/vga */ + if ((unsigned long)Base < 0xA0000 || (unsigned long)Base >= 0xC0000) + { + FatalError("%s: Address 0x%x outside allowable range\n", + "xf86MapVidMem", Base); + } + base = mmap(0, Size, PROT_READ|PROT_WRITE, MAP_FLAGS, + xf86Info.screenFd, + (unsigned long)Base - 0xA0000); + if (base == MAP_FAILED) + { + FatalError("xf86MapVidMem: Could not mmap /dev/vga (%s)\n", + strerror(errno)); + } + return(base); +} + +static void +unmapVidMem(int ScreenNum, pointer Base, unsigned long Size) +{ + munmap((caddr_t)Base, Size); +} + +/* + * Read BIOS via mmap()ing DEV_MEM + */ + +int +xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf, + int Len) +{ + unsigned char *ptr; + int psize; + int mlen; + + checkDevMem(TRUE); + if (devMemFd == -1) { + return(-1); + } + + psize = xf86getpagesize(); + Offset += Base & (psize - 1); + Base &= ~(psize - 1); + mlen = (Offset + Len + psize - 1) & ~(psize - 1); + ptr = (unsigned char *)mmap((caddr_t)0, mlen, PROT_READ, + MAP_SHARED, devMemFd, (off_t)Base+BUS_BASE); + if ((long)ptr == -1) + { + xf86Msg(X_WARNING, + "xf86ReadBIOS: %s mmap[s=%x,a=%x,o=%x] failed (%s)\n", + DEV_MEM, Len, Base, Offset, strerror(errno)); + return(-1); + } +#ifdef DEBUG + ErrorF("xf86ReadBIOS: BIOS at 0x%08x has signature 0x%04x\n", + Base, ptr[0] | (ptr[1] << 8)); +#endif + (void)memcpy(Buf, (void *)(ptr + Offset), Len); + (void)munmap((caddr_t)ptr, mlen); +#ifdef DEBUG + xf86MsgVerb(X_INFO, 3, "xf86ReadBIOS(%x, %x, Buf, %x)" + "-> %02x %02x %02x %02x...\n", + Base, Offset, Len, Buf[0], Buf[1], Buf[2], Buf[3]); +#endif + return(Len); +} + + +/* XXX This needs to be updated for the ND */ + +/* +** Find out whether the console driver provides memory mapping information +** for the specified region and return the map_info pointer. Print a warning if required. +*/ +static struct memAccess * +checkMapInfo(Bool warn, int Region) +{ + struct memAccess *memAccP; + + switch (Region) + { + case VGA_REGION: + memAccP = &vgaMemInfo; + break; + + case LINEAR_REGION: + memAccP = &linearMemInfo; + break; + + case MMIO_REGION: + memAccP = &ioMemInfo; + break; + + default: + return NULL; + break; + } + + if(!memAccP->Checked) + { + if(ioctl(xf86Info.screenFd, memAccP->ioctl, &(memAccP->memInfo)) == -1) + { + if(warn) + { + xf86Msg(X_WARNING, + "checkMapInfo: failed to get map info for region %d\n\t(%s)\n", + Region, strerror(errno)); + } + } + else + { + if(memAccP->memInfo.u.map_info_mmap.map_offset + != MAP_INFO_UNKNOWN) + memAccP->OK = TRUE; + } + memAccP->Checked = TRUE; + } + if (memAccP->OK) + { + return memAccP; + } + else + { + return NULL; + } +} + +static pointer +xf86MapInfoMap(struct memAccess *memInfoP, pointer Base, unsigned long Size) +{ + struct map_info *mapInfoP = &(memInfoP->memInfo); + + if (mapInfoP->u.map_info_mmap.map_size == MAP_INFO_UNKNOWN) + { + Size = (unsigned long)Base + Size; + } + else + { + Size = mapInfoP->u.map_info_mmap.map_size; + } + + switch(mapInfoP->method) + { + case MAP_MMAP: + /* Need to remap if size is unknown because we may not have + mapped the whole region initially */ + if(memInfoP->regionVirtBase == NULL || + mapInfoP->u.map_info_mmap.map_size == MAP_INFO_UNKNOWN) + { + if((memInfoP->regionVirtBase = + mmap((caddr_t)0, + Size, + PROT_READ|PROT_WRITE, + MAP_SHARED, + xf86Info.screenFd, + (unsigned long)mapInfoP->u.map_info_mmap.map_offset)) + == (pointer)-1) + { + FatalError("xf86MapInfoMap: Failed to map memory at 0x%x\n\t%s\n", + mapInfoP->u.map_info_mmap.map_offset, strerror(errno)); + } + if(mapInfoP->u.map_info_mmap.internal_offset > 0) + memInfoP->regionVirtBase += + mapInfoP->u.map_info_mmap.internal_offset; + } + break; + + default: + FatalError("xf86MapInfoMap: Unsuported mapping method\n"); + break; + } + + return (pointer)((int)memInfoP->regionVirtBase + (int)Base); +} + +static void +xf86MapInfoUnmap(struct memAccess *memInfoP, unsigned long Size) +{ + struct map_info *mapInfoP = &(memInfoP->memInfo); + + switch(mapInfoP->method) + { + case MAP_MMAP: + if(memInfoP->regionVirtBase != NULL) + { + if(mapInfoP->u.map_info_mmap.map_size != MAP_INFO_UNKNOWN) + Size = mapInfoP->u.map_info_mmap.map_size; + munmap((caddr_t)memInfoP->regionVirtBase, Size); + memInfoP->regionVirtBase = NULL; + } + break; + default: + FatalError("xf86MapInfoMap: Unsuported mapping method\n"); + break; + } +} + +static pointer +armMapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags) +{ + struct memAccess *memInfoP; + + if((memInfoP = checkMapInfo(FALSE, Region)) != NULL) + { + /* + ** xf86 passes in a physical address offset from the start + ** of physical memory, but xf86MapInfoMap expects an + ** offset from the start of the specified region - it gets + ** the physical address of the region from the display driver. + */ + switch(Region) + { + case LINEAR_REGION: + if (vgaPhysLinearBase) + { + Base -= vgaPhysLinearBase; + } + break; + case VGA_REGION: + Base -= 0xA0000; + break; + } + + base = xf86MapInfoMap(memInfoP, Base, Size); + return (base); + } + return mapVidMem(ScreenNum, Base, Size, flags); +} + +static void +armUnmapVidMem(int ScreenNum, pointer Base, unsigned long Size) +{ + struct memAccess *memInfoP; + + if((memInfoP = checkMapInfo(FALSE, Region)) != NULL) + { + xf86MapInfoUnmap(memInfoP, Base, Size); + } + unmapVidMem(ScreenNum, Base, Size); +} + +#ifdef USE_DEV_IO +static int IoFd = -1; + +void +xf86EnableIO() +{ + if (IoFd >= 0) + return; + + if ((IoFd = open("/dev/io", O_RDWR)) == -1) + { + FatalError("xf86EnableIO: " + "Failed to open /dev/io for extended I/O\n"); + } + return; +} + +void +xf86DisableIO() +{ + if (IoFd < 0) + return; + + close(IoFd); + IoFd = -1; + return; +} + +#endif + +#if defined(USE_ARC_MMAP) || defined(__arm32__) + +void +xf86EnableIO() +{ + int fd; + pointer base; + + if (ExtendedEnabled) + return; + + if ((fd = open("/dev/ttyC0", O_RDWR)) >= 0) { + /* Try to map a page at the pccons I/O space */ + base = (pointer)mmap((caddr_t)0, 65536, PROT_READ|PROT_WRITE, + MAP_FLAGS, fd, (off_t)0x0000); + + if (base != (pointer)-1) { + IOPortBase = base; + } + else { + FatalError("EnableIO: failed to mmap %s (%s)\n", + "/dev/ttyC0", strerror(errno)); + } + } + else { + FatalError("EnableIO: failed to open %s (%s)\n", + "/dev/ttyC0", strerror(errno)); + } + + ExtendedEnabled = TRUE; + + return; +} + +void +xf86DisableIO() +{ + return; +} + +#endif /* USE_ARC_MMAP */ + + +/***************************************************************************/ +/* Interrupt Handling section */ +/***************************************************************************/ + +Bool +xf86DisableInterrupts() +{ + + return(TRUE); +} + +void +xf86EnableInterrupts() +{ + + return; +} + + + +#if 0 +/* + * XXX This is here for reference. It needs to be handled differently for the + * ND. + */ +#if defined(USE_ARC_MMAP) || defined(__arm32__) + +#ifdef USE_ARM32_MMAP +#define DEV_MEM_IOBASE 0x43000000 +#endif + +static Bool ScreenEnabled[MAXSCREENS]; +static Bool ExtendedEnabled = FALSE; +static Bool InitDone = FALSE; + +void +xf86EnableIOPorts(ScreenNum) +int ScreenNum; +{ + int i; + int fd; + pointer base; + +#ifdef __arm32__ + struct memAccess *memInfoP; + int *Size; +#endif + + ScreenEnabled[ScreenNum] = TRUE; + + if (ExtendedEnabled) + return; + +#ifdef USE_ARC_MMAP + if ((fd = open("/dev/ttyC0", O_RDWR)) >= 0) { + /* Try to map a page at the pccons I/O space */ + base = (pointer)mmap((caddr_t)0, 65536, PROT_READ|PROT_WRITE, + MAP_FLAGS, fd, (off_t)0x0000); + + if (base != (pointer)-1) { + IOPortBase = base; + } + else { + xf86Msg(X_ERROR, + "EnableIOPorts: failed to mmap %s (%s)\n", + "/dev/ttyC0", strerror(errno)); + } + } + else { + xf86Msg(X_ERROR, "EnableIOPorts: failed to open %s (%s)\n", + "/dev/ttyC0", strerror(errno)); + } +#endif + +#ifdef __arm32__ + IOPortBase = (unsigned int)-1; + + if((memInfoP = checkMapInfo(TRUE, MMIO_REGION)) != NULL) + { + /* + * xf86MapInfoMap maps an offset from the start of video IO + * space (e.g. 0x3B0), but IOPortBase is expected to map to + * physical address 0x000, so subtract the start of video I/O + * space from the result. This is safe for now becase we + * actually mmap the start of the page, then the start of video + * I/O space is added as an internal offset. + */ + IOPortBase = (unsigned int)xf86MapInfoMap(memInfoP, + (caddr_t)0x0, 0L) + - memInfoP->memInfo.u.map_info_mmap.internal_offset; + ExtendedEnabled = TRUE; + return; + } +#ifdef USE_ARM32_MMAP + checkDevMem(TRUE); + + if (devMemFd >= 0 && useDevMem) + { + base = (pointer)mmap((caddr_t)0, 0x400, PROT_READ|PROT_WRITE, + MAP_FLAGS, devMemFd, (off_t)DEV_MEM_IOBASE); + + if (base != (pointer)-1) + IOPortBase = (unsigned int)base; + } + + if (IOPortBase == (unsigned int)-1) + { + FatalError("xf86EnableIOPorts: failed to open mem device or map IO base. \n\ +Make sure you have the Aperture Driver installed, or a kernel built with the INSECURE option\n"); + } +#else + /* We don't have the IOBASE, so we can't map the address */ + FatalError("xf86EnableIOPorts: failed to open mem device or map IO base. \n\ +Try building the server with USE_ARM32_MMAP defined\n"); +#endif +#endif + + ExtendedEnabled = TRUE; + + return; +} + +void +xf86DisableIOPorts(ScreenNum) +int ScreenNum; +{ + int i; +#ifdef __arm32__ + struct memAccess *memInfoP; +#endif + + ScreenEnabled[ScreenNum] = FALSE; + +#ifdef __arm32__ + if((memInfoP = checkMapInfo(FALSE, MMIO_REGION)) != NULL) + { + xf86MapInfoUnmap(memInfoP, 0); + } +#endif + +#ifdef USE_ARM32_MMAP + if (!ExtendedEnabled) + return; + + for (i = 0; i < MAXSCREENS; i++) + if (ScreenEnabled[i]) + return; + + munmap((caddr_t)IOPortBase, 0x400); + IOPortBase = (unsigned int)-1; + ExtendedEnabled = FALSE; +#endif + + return; +} + +#endif /* USE_ARC_MMAP || USE_ARM32_MMAP */ +#endif + + diff --git a/hw/xfree86/os-support/bsd/bsdResource.c b/hw/xfree86/os-support/bsd/bsdResource.c new file mode 100644 index 000000000..f999561cf --- /dev/null +++ b/hw/xfree86/os-support/bsd/bsdResource.c @@ -0,0 +1,190 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/bsdResource.c,v 1.8 2002/05/22 21:38:29 herrb Exp $ */ + +/* Resource information code */ + +#include "X.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86Privstr.h" +#include "xf86Pci.h" +#include "xf86Resources.h" +#define NEED_OS_RAC_PROTOS +#include "xf86_OSlib.h" + +/* Avoid Imakefile changes */ +#include "bus/Pci.h" + +resRange PciAvoid[] = {_PCI_AVOID_PC_STYLE, _END}; + +#ifdef INCLUDE_XF86_NO_DOMAIN + +#if defined(__alpha__) || defined(__sparc64__) + +resPtr +xf86BusAccWindowsFromOS(void) +{ + resPtr ret = NULL; + resRange range; + + RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + + RANGE(range, 0x00000000, 0xffffffff, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); + return ret; +} + +resPtr +xf86PciBusAccWindowsFromOS(void) +{ + resPtr ret = NULL; + resRange range; + + /* + * Only allow the upper half of the pci memory range to be used + * for allocation. The lower half includes magic regions for DMA. + * XXX this is not right for XP1000's and similar where we use the + * region 0x40000000-0xbfffffff for DMA but this only matters if + * the bios screws up the pci region mappings. + */ + RANGE(range, 0x80000000, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + + RANGE(range, 0x00000000, 0xffffffff, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); + return ret; +} + +#ifdef INCLUDE_UNUSED + +resPtr +xf86IsaBusAccWindowsFromOS(void) +{ + resPtr ret = NULL; + resRange range; + + RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + + RANGE(range, 0x00000000, 0xffffffff, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); + return ret; +} + +#endif /* INCLUDE_UNUSED */ + +resPtr +xf86AccResFromOS(resPtr ret) +{ + resRange range; + + /* + * Fallback is to claim the following areas: + * + * 0x000c0000 - 0x000effff location of VGA and other extensions ROMS + */ + + RANGE(range, 0x000c0000, 0x000effff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + + /* + * Fallback would be to claim well known ports in the 0x0 - 0x3ff range + * along with their sparse I/O aliases, but that's too imprecise. Instead + * claim a bare minimum here. + */ + RANGE(range, 0x00000000, 0x000000ff, ResExcIoBlock); /* For mainboard */ + ret = xf86AddResToList(ret, &range, -1); + + /* + * At minimum, the top and bottom resources must be claimed, so that + * resources that are (or appear to be) unallocated can be relocated. + */ + RANGE(range, 0x00000000, 0x00000000, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0xffffffff, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); +/* RANGE(range, 0x00000000, 0x00000000, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); */ + RANGE(range, 0xffffffff, 0xffffffff, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); + + /* XXX add others */ + return ret; +} + +#elif defined(__powerpc__) + +resPtr +xf86BusAccWindowsFromOS(void) +{ + resPtr ret = NULL; + resRange range; + + RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + + RANGE(range, 0x00000000, 0x0000ffff, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); + return ret; +} + +resPtr +xf86PciBusAccWindowsFromOS(void) +{ + resPtr ret = NULL; + resRange range; + + RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + + RANGE(range, 0x00000000, 0x0000ffff, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); + return ret; +} + +#ifdef INCLUDE_UNUSED + +resPtr +xf86IsaBusAccWindowsFromOS(void) +{ + resPtr ret = NULL; + resRange range; + + RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + + RANGE(range, 0x00000000, 0x0000ffff, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); + return ret; +} + +#endif /* INCLUDE_UNUSED */ + +resPtr +xf86AccResFromOS(resPtr ret) +{ + resRange range; + + /* + * At minimum, the top and bottom resources must be claimed, so that + * resources that are (or appear to be) unallocated can be relocated. + */ + RANGE(range, 0x00000000, 0x00000000, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0xffffffff, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x00000000, 0x00000000, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x0000ffff, 0x0000ffff, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); + + return ret; +} + +#else + +#error : Put your platform dependent code here!! + +#endif + +#endif /* INCLUDE_XF86_NO_DOMAIN */ diff --git a/hw/xfree86/os-support/bsd/bsd_KbdMap.c b/hw/xfree86/os-support/bsd/bsd_KbdMap.c new file mode 100644 index 000000000..a47dc2384 --- /dev/null +++ b/hw/xfree86/os-support/bsd/bsd_KbdMap.c @@ -0,0 +1,1075 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_KbdMap.c,v 1.1 2002/10/11 01:40:34 dawes Exp $ */ + +/* + * Slightly modified xf86KbdBSD.c which is + * + * Derived from xf86Kbd.c by S_ren Schmidt (sos@login.dkuug.dk) + * which is Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. + * and from xf86KbdCODrv.c by Holger Veit + */ + +#include "X.h" +#include "Xmd.h" +#include "input.h" +#include "scrnintstr.h" + +#include "compiler.h" + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "xf86Xinput.h" +#include "xf86OSKbd.h" +#include "atKeynames.h" +#include "xf86Keymap.h" +#include "bsd_kbd.h" + +#if (defined(SYSCONS_SUPPORT) || defined(PCVT_SUPPORT)) && defined(GIO_KEYMAP) +#define KD_GET_ENTRY(i,n) \ + eascii_to_x[((keymap.key[i].spcl << (n+1)) & 0x100) + keymap.key[i].map[n]] + +static unsigned char remap[NUM_KEYCODES] = { + 0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00 - 0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08 - 0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10 - 0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18 - 0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 - 0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28 - 0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0, /* 0x30 - 0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38 - 0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0, /* 0x40 - 0x47 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x48 - 0x4f */ + 0, 0, 0, 0, 0, 0, 0x56, 0x57, /* 0x50 - 0x57 */ + 0x58, 0, 0, 0, 0, 0, 0, 0, /* 0x58 - 0x5f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x67 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x68 - 0x6f */ + 0, 0, 0x69, 0x65, 0, 0, 0, 0, /* 0x70 - 0x77 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x78 - 0x7f */ +}; + +/* This table assumes the ibm code page 437 coding for characters + * > 0x80. They are returned in this form by PCVT */ +static KeySym eascii_to_x[512] = { + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + XK_BackSpace, XK_Tab, XK_Linefeed, NoSymbol, + NoSymbol, XK_Return, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, XK_Escape, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + XK_space, XK_exclam, XK_quotedbl, XK_numbersign, + XK_dollar, XK_percent, XK_ampersand, XK_apostrophe, + XK_parenleft, XK_parenright, XK_asterisk, XK_plus, + XK_comma, XK_minus, XK_period, XK_slash, + XK_0, XK_1, XK_2, XK_3, + XK_4, XK_5, XK_6, XK_7, + XK_8, XK_9, XK_colon, XK_semicolon, + XK_less, XK_equal, XK_greater, XK_question, + XK_at, XK_A, XK_B, XK_C, + XK_D, XK_E, XK_F, XK_G, + XK_H, XK_I, XK_J, XK_K, + XK_L, XK_M, XK_N, XK_O, + XK_P, XK_Q, XK_R, XK_S, + XK_T, XK_U, XK_V, XK_W, + XK_X, XK_Y, XK_Z, XK_bracketleft, + XK_backslash, XK_bracketright,XK_asciicircum, XK_underscore, + XK_grave, XK_a, XK_b, XK_c, + XK_d, XK_e, XK_f, XK_g, + XK_h, XK_i, XK_j, XK_k, + XK_l, XK_m, XK_n, XK_o, + XK_p, XK_q, XK_r, XK_s, + XK_t, XK_u, XK_v, XK_w, + XK_x, XK_y, XK_z, XK_braceleft, + XK_bar, XK_braceright, XK_asciitilde, XK_Delete, + XK_Ccedilla, XK_udiaeresis, XK_eacute, XK_acircumflex, + XK_adiaeresis, XK_agrave, XK_aring, XK_ccedilla, + XK_ecircumflex, XK_ediaeresis, XK_egrave, XK_idiaeresis, + XK_icircumflex, XK_igrave, XK_Adiaeresis, XK_Aring, + XK_Eacute, XK_ae, XK_AE, XK_ocircumflex, + XK_odiaeresis, XK_ograve, XK_ucircumflex, XK_ugrave, + XK_ydiaeresis, XK_Odiaeresis, XK_Udiaeresis, XK_cent, + XK_sterling, XK_yen, XK_paragraph, XK_section, + XK_aacute, XK_iacute, XK_oacute, XK_uacute, + XK_ntilde, XK_Ntilde, XK_ordfeminine, XK_masculine, + XK_questiondown,XK_hyphen, XK_notsign, XK_onehalf, + XK_onequarter, XK_exclamdown, XK_guillemotleft,XK_guillemotright, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + XK_Greek_alpha, XK_ssharp, XK_Greek_GAMMA, XK_Greek_pi, + XK_Greek_SIGMA, XK_Greek_sigma, XK_mu, XK_Greek_tau, + XK_Greek_PHI, XK_Greek_THETA, XK_Greek_OMEGA, XK_Greek_delta, + XK_infinity, XK_Ooblique, XK_Greek_epsilon, XK_intersection, + XK_identical, XK_plusminus, XK_greaterthanequal, XK_lessthanequal, + XK_topintegral, XK_botintegral, XK_division, XK_similarequal, + XK_degree, NoSymbol, NoSymbol, XK_radical, + XK_Greek_eta, XK_twosuperior, XK_periodcentered, NoSymbol, + + /* + * special marked entries (256 + x) + */ + + /* This has been checked against what syscons actually does */ + NoSymbol, NoSymbol, XK_Shift_L, XK_Shift_R, + XK_Caps_Lock, XK_Num_Lock, XK_Scroll_Lock, XK_Alt_L, + XK_ISO_Left_Tab,XK_Control_L, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, XK_F1, + XK_F2, XK_F3, XK_F4, XK_F5, + XK_F6, XK_F7, XK_F8, XK_F9, + XK_F10, XK_F11, XK_F12, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + XK_Control_R, XK_Alt_R, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol +}; + +#ifdef __OpenBSD__ +/* don't mark AltR and CtrlR for remapping, since they + * cannot be remapped by pccons */ +static unsigned char pccons_remap[128] = { + 0, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 0x00 - 0x07 */ + 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, /* 0x08 - 0x0f */ + 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, /* 0x10 - 0x17 */ + 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, /* 0x18 - 0x1f */ + 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, /* 0x20 - 0x27 */ + 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, /* 0x28 - 0x2f */ + 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0, /* 0x30 - 0x37 */ + 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, /* 0x38 - 0x3f */ + 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0, /* 0x40 - 0x47 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x48 - 0x4f */ + 0, 0, 0, 0, 0, 0, 0x56, 0x57, /* 0x50 - 0x57 */ + 0x58, 0, 0, 0, 0, 0, 0, 0, /* 0x58 - 0x5f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x60 - 0x67 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x68 - 0x6f */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x70 - 0x77 */ + 0, 0, 0, 0, 0, 0, 0, 0, /* 0x78 - 0x7f */ +}; + +/* This table assumes an iso8859_1 encoding for the characters + * > 80, as returned by pccons */ +static KeySym latin1_to_x[256] = { + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + XK_BackSpace, XK_Tab, XK_Linefeed, NoSymbol, + NoSymbol, XK_Return, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, XK_Escape, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + XK_space, XK_exclam, XK_quotedbl, XK_numbersign, + XK_dollar, XK_percent, XK_ampersand, XK_apostrophe, + XK_parenleft, XK_parenright, XK_asterisk, XK_plus, + XK_comma, XK_minus, XK_period, XK_slash, + XK_0, XK_1, XK_2, XK_3, + XK_4, XK_5, XK_6, XK_7, + XK_8, XK_9, XK_colon, XK_semicolon, + XK_less, XK_equal, XK_greater, XK_question, + XK_at, XK_A, XK_B, XK_C, + XK_D, XK_E, XK_F, XK_G, + XK_H, XK_I, XK_J, XK_K, + XK_L, XK_M, XK_N, XK_O, + XK_P, XK_Q, XK_R, XK_S, + XK_T, XK_U, XK_V, XK_W, + XK_X, XK_Y, XK_Z, XK_bracketleft, + XK_backslash, XK_bracketright,XK_asciicircum, XK_underscore, + XK_grave, XK_a, XK_b, XK_c, + XK_d, XK_e, XK_f, XK_g, + XK_h, XK_i, XK_j, XK_k, + XK_l, XK_m, XK_n, XK_o, + XK_p, XK_q, XK_r, XK_s, + XK_t, XK_u, XK_v, XK_w, + XK_x, XK_y, XK_z, XK_braceleft, + XK_bar, XK_braceright, XK_asciitilde, XK_Delete, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + XK_nobreakspace,XK_exclamdown, XK_cent, XK_sterling, + XK_currency, XK_yen, XK_brokenbar, XK_section, + XK_diaeresis, XK_copyright, XK_ordfeminine, XK_guillemotleft, + XK_notsign, XK_hyphen, XK_registered, XK_macron, + XK_degree, XK_plusminus, XK_twosuperior, XK_threesuperior, + XK_acute, XK_mu, XK_paragraph, XK_periodcentered, + XK_cedilla, XK_onesuperior, XK_masculine, XK_guillemotright, + XK_onequarter, XK_onehalf, XK_threequarters,XK_questiondown, + XK_Agrave, XK_Aacute, XK_Acircumflex, XK_Atilde, + XK_Adiaeresis, XK_Aring, XK_AE, XK_Ccedilla, + XK_Egrave, XK_Eacute, XK_Ecircumflex, XK_Ediaeresis, + XK_Igrave, XK_Iacute, XK_Icircumflex, XK_Idiaeresis, + XK_ETH, XK_Ntilde, XK_Ograve, XK_Oacute, + XK_Ocircumflex, XK_Otilde, XK_Odiaeresis, XK_multiply, + XK_Ooblique, XK_Ugrave, XK_Uacute, XK_Ucircumflex, + XK_Udiaeresis, XK_Yacute, XK_THORN, XK_ssharp, + XK_agrave, XK_aacute, XK_acircumflex, XK_atilde, + XK_adiaeresis, XK_aring, XK_ae, XK_ccedilla, + XK_egrave, XK_eacute, XK_ecircumflex, XK_ediaeresis, + XK_igrave, XK_iacute, XK_icircumflex, XK_idiaeresis, + XK_eth, XK_ntilde, XK_ograve, XK_oacute, + XK_ocircumflex, XK_otilde, XK_odiaeresis, XK_division, + XK_oslash, XK_ugrave, XK_uacute, XK_ucircumflex, + XK_udiaeresis, XK_yacute, XK_thorn, XK_ydiaeresis + }; +#endif + +#ifdef SYSCONS_SUPPORT +static +unsigned char sysconsCODEMap[] = { + KEY_KP_Enter, KEY_RCtrl, KEY_KP_Divide, KEY_Print, + KEY_AltLang, KEY_KP_7, KEY_KP_8, KEY_KP_9, + KEY_KP_4, KEY_KP_6, KEY_KP_1, KEY_KP_2, + KEY_KP_3, KEY_KP_0, KEY_KP_Decimal, KEY_Pause, + KEY_LMeta, KEY_RMeta, KEY_Menu, KEY_Break +}; +static +TransMapRec sysconsCODE = { + 0x59, + 0x6d, + sysconsCODEMap +}; +#endif +#endif /* SYSCONS_SUPPORT || PCVT_SUPPORT */ + +#ifdef WSCONS_SUPPORT + +static CARD8 wsUsbMap[] = { + /* 0 */ KEY_NOTUSED, + /* 1 */ KEY_NOTUSED, + /* 2 */ KEY_NOTUSED, + /* 3 */ KEY_NOTUSED, + /* 4 */ KEY_A, + /* 5 */ KEY_B, + /* 6 */ KEY_C, + /* 7 */ KEY_D, + /* 8 */ KEY_E, + /* 9 */ KEY_F, + /* 10 */ KEY_G, + /* 11 */ KEY_H, + /* 12 */ KEY_I, + /* 13 */ KEY_J, + /* 14 */ KEY_K, + /* 15 */ KEY_L, + /* 16 */ KEY_M, + /* 17 */ KEY_N, + /* 18 */ KEY_O, + /* 19 */ KEY_P, + /* 20 */ KEY_Q, + /* 21 */ KEY_R, + /* 22 */ KEY_S, + /* 23 */ KEY_T, + /* 24 */ KEY_U, + /* 25 */ KEY_V, + /* 26 */ KEY_W, + /* 27 */ KEY_X, + /* 28 */ KEY_Y, + /* 29 */ KEY_Z, + /* 30 */ KEY_1, /* 1 !*/ + /* 31 */ KEY_2, /* 2 @ */ + /* 32 */ KEY_3, /* 3 # */ + /* 33 */ KEY_4, /* 4 $ */ + /* 34 */ KEY_5, /* 5 % */ + /* 35 */ KEY_6, /* 6 ^ */ + /* 36 */ KEY_7, /* 7 & */ + /* 37 */ KEY_8, /* 8 * */ + /* 38 */ KEY_9, /* 9 ( */ + /* 39 */ KEY_0, /* 0 ) */ + /* 40 */ KEY_Enter, /* Return */ + /* 41 */ KEY_Escape, /* Escape */ + /* 42 */ KEY_BackSpace, /* Backspace Delete */ + /* 43 */ KEY_Tab, /* Tab */ + /* 44 */ KEY_Space, /* Space */ + /* 45 */ KEY_Minus, /* - _ */ + /* 46 */ KEY_Equal, /* = + */ + /* 47 */ KEY_LBrace, /* [ { */ + /* 48 */ KEY_RBrace, /* ] } */ + /* 49 */ KEY_BSlash, /* \ | */ + /* 50 */ KEY_BSlash2, /* \ _ # ~ on some keyboards */ + /* 51 */ KEY_SemiColon, /* ; : */ + /* 52 */ KEY_Quote, /* ' " */ + /* 53 */ KEY_Tilde, /* ` ~ */ + /* 54 */ KEY_Comma, /* , < */ + /* 55 */ KEY_Period, /* . > */ + /* 56 */ KEY_Slash, /* / ? */ + /* 57 */ KEY_CapsLock, /* Caps Lock */ + /* 58 */ KEY_F1, /* F1 */ + /* 59 */ KEY_F2, /* F2 */ + /* 60 */ KEY_F3, /* F3 */ + /* 61 */ KEY_F4, /* F4 */ + /* 62 */ KEY_F5, /* F5 */ + /* 63 */ KEY_F6, /* F6 */ + /* 64 */ KEY_F7, /* F7 */ + /* 65 */ KEY_F8, /* F8 */ + /* 66 */ KEY_F9, /* F9 */ + /* 67 */ KEY_F10, /* F10 */ + /* 68 */ KEY_F11, /* F11 */ + /* 69 */ KEY_F12, /* F12 */ + /* 70 */ KEY_Print, /* PrintScrn SysReq */ + /* 71 */ KEY_ScrollLock, /* Scroll Lock */ + /* 72 */ KEY_Pause, /* Pause Break */ + /* 73 */ KEY_Insert, /* Insert XXX Help on some Mac Keyboards */ + /* 74 */ KEY_Home, /* Home */ + /* 75 */ KEY_PgUp, /* Page Up */ + /* 76 */ KEY_Delete, /* Delete */ + /* 77 */ KEY_End, /* End */ + /* 78 */ KEY_PgDown, /* Page Down */ + /* 79 */ KEY_Right, /* Right Arrow */ + /* 80 */ KEY_Left, /* Left Arrow */ + /* 81 */ KEY_Down, /* Down Arrow */ + /* 82 */ KEY_Up, /* Up Arrow */ + /* 83 */ KEY_NumLock, /* Num Lock */ + /* 84 */ KEY_KP_Divide, /* Keypad / */ + /* 85 */ KEY_KP_Multiply, /* Keypad * */ + /* 86 */ KEY_KP_Minus, /* Keypad - */ + /* 87 */ KEY_KP_Plus, /* Keypad + */ + /* 88 */ KEY_KP_Enter, /* Keypad Enter */ + /* 89 */ KEY_KP_1, /* Keypad 1 End */ + /* 90 */ KEY_KP_2, /* Keypad 2 Down */ + /* 91 */ KEY_KP_3, /* Keypad 3 Pg Down */ + /* 92 */ KEY_KP_4, /* Keypad 4 Left */ + /* 93 */ KEY_KP_5, /* Keypad 5 */ + /* 94 */ KEY_KP_6, /* Keypad 6 */ + /* 95 */ KEY_KP_7, /* Keypad 7 Home */ + /* 96 */ KEY_KP_8, /* Keypad 8 Up */ + /* 97 */ KEY_KP_9, /* KEypad 9 Pg Up */ + /* 98 */ KEY_KP_0, /* Keypad 0 Ins */ + /* 99 */ KEY_KP_Decimal, /* Keypad . Del */ + /* 100 */ KEY_Less, /* < > on some keyboards */ + /* 101 */ KEY_Menu, /* Menu */ + /* 102 */ KEY_NOTUSED, + /* 103 */ KEY_KP_Equal, /* Keypad = on Mac keyboards */ + /* 104 */ KEY_NOTUSED, + /* 105 */ KEY_NOTUSED, + /* 106 */ KEY_NOTUSED, + /* 107 */ KEY_NOTUSED, + /* 108 */ KEY_NOTUSED, + /* 109 */ KEY_NOTUSED, + /* 110 */ KEY_NOTUSED, + /* 111 */ KEY_NOTUSED, + /* 112 */ KEY_NOTUSED, + /* 113 */ KEY_NOTUSED, + /* 114 */ KEY_NOTUSED, + /* 115 */ KEY_NOTUSED, + /* 116 */ KEY_NOTUSED, + /* 117 */ KEY_NOTUSED, + /* 118 */ KEY_NOTUSED, + /* 119 */ KEY_NOTUSED, + /* 120 */ KEY_NOTUSED, + /* 121 */ KEY_NOTUSED, + /* 122 */ KEY_NOTUSED, + /* 123 */ KEY_NOTUSED, + /* 124 */ KEY_NOTUSED, + /* 125 */ KEY_NOTUSED, + /* 126 */ KEY_NOTUSED, + /* 127 */ KEY_NOTUSED, + /* 128 */ KEY_NOTUSED, + /* 129 */ KEY_NOTUSED, + /* 130 */ KEY_NOTUSED, + /* 131 */ KEY_NOTUSED, + /* 132 */ KEY_NOTUSED, + /* 133 */ KEY_NOTUSED, + /* 134 */ KEY_NOTUSED, + /* 135 */ KEY_NOTUSED, + /* 136 */ KEY_NOTUSED, + /* 137 */ KEY_NOTUSED, + /* 138 */ KEY_NOTUSED, + /* 139 */ KEY_NOTUSED, + /* 140 */ KEY_NOTUSED, + /* 141 */ KEY_NOTUSED, + /* 142 */ KEY_NOTUSED, + /* 143 */ KEY_NOTUSED, + /* 144 */ KEY_NOTUSED, + /* 145 */ KEY_NOTUSED, + /* 146 */ KEY_NOTUSED, + /* 147 */ KEY_NOTUSED, + /* 148 */ KEY_NOTUSED, + /* 149 */ KEY_NOTUSED, + /* 150 */ KEY_NOTUSED, + /* 151 */ KEY_NOTUSED, + /* 152 */ KEY_NOTUSED, + /* 153 */ KEY_NOTUSED, + /* 154 */ KEY_NOTUSED, + /* 155 */ KEY_NOTUSED, + /* 156 */ KEY_NOTUSED, + /* 157 */ KEY_NOTUSED, + /* 158 */ KEY_NOTUSED, + /* 159 */ KEY_NOTUSED, + /* 160 */ KEY_NOTUSED, + /* 161 */ KEY_NOTUSED, + /* 162 */ KEY_NOTUSED, + /* 163 */ KEY_NOTUSED, + /* 164 */ KEY_NOTUSED, + /* 165 */ KEY_NOTUSED, + /* 166 */ KEY_NOTUSED, + /* 167 */ KEY_NOTUSED, + /* 168 */ KEY_NOTUSED, + /* 169 */ KEY_NOTUSED, + /* 170 */ KEY_NOTUSED, + /* 171 */ KEY_NOTUSED, + /* 172 */ KEY_NOTUSED, + /* 173 */ KEY_NOTUSED, + /* 174 */ KEY_NOTUSED, + /* 175 */ KEY_NOTUSED, + /* 176 */ KEY_NOTUSED, + /* 177 */ KEY_NOTUSED, + /* 178 */ KEY_NOTUSED, + /* 179 */ KEY_NOTUSED, + /* 180 */ KEY_NOTUSED, + /* 181 */ KEY_NOTUSED, + /* 182 */ KEY_NOTUSED, + /* 183 */ KEY_NOTUSED, + /* 184 */ KEY_NOTUSED, + /* 185 */ KEY_NOTUSED, + /* 186 */ KEY_NOTUSED, + /* 187 */ KEY_NOTUSED, + /* 188 */ KEY_NOTUSED, + /* 189 */ KEY_NOTUSED, + /* 190 */ KEY_NOTUSED, + /* 191 */ KEY_NOTUSED, + /* 192 */ KEY_NOTUSED, + /* 193 */ KEY_NOTUSED, + /* 194 */ KEY_NOTUSED, + /* 195 */ KEY_NOTUSED, + /* 196 */ KEY_NOTUSED, + /* 197 */ KEY_NOTUSED, + /* 198 */ KEY_NOTUSED, + /* 199 */ KEY_NOTUSED, + /* 200 */ KEY_NOTUSED, + /* 201 */ KEY_NOTUSED, + /* 202 */ KEY_NOTUSED, + /* 203 */ KEY_NOTUSED, + /* 204 */ KEY_NOTUSED, + /* 205 */ KEY_NOTUSED, + /* 206 */ KEY_NOTUSED, + /* 207 */ KEY_NOTUSED, + /* 208 */ KEY_NOTUSED, + /* 209 */ KEY_NOTUSED, + /* 210 */ KEY_NOTUSED, + /* 211 */ KEY_NOTUSED, + /* 212 */ KEY_NOTUSED, + /* 213 */ KEY_NOTUSED, + /* 214 */ KEY_NOTUSED, + /* 215 */ KEY_NOTUSED, + /* 216 */ KEY_NOTUSED, + /* 217 */ KEY_NOTUSED, + /* 218 */ KEY_NOTUSED, + /* 219 */ KEY_NOTUSED, + /* 220 */ KEY_NOTUSED, + /* 221 */ KEY_NOTUSED, + /* 222 */ KEY_NOTUSED, + /* 223 */ KEY_NOTUSED, + /* 224 */ KEY_LCtrl, /* Left Control */ + /* 225 */ KEY_ShiftL, /* Left Shift */ + /* 226 */ KEY_Alt, /* Left Alt */ + /* 227 */ KEY_LMeta, /* Left Meta */ + /* 228 */ KEY_RCtrl, /* Right Control */ + /* 229 */ KEY_ShiftR, /* Right Shift */ + /* 230 */ KEY_AltLang, /* Right Alt, AKA AltGr */ + /* 231 */ KEY_LMeta, /* Right Meta XXX */ +}; +#define WS_USB_MAP_SIZE (sizeof(wsUsbMap)/sizeof(unsigned char)) + +static +TransMapRec wsUsb = { + 0, + WS_USB_MAP_SIZE, + wsUsbMap +}; + +/* Map for adb keyboards */ +static CARD8 wsAdbMap[] = { + /* 0 */ KEY_A, + /* 1 */ KEY_S, + /* 2 */ KEY_D, + /* 3 */ KEY_F, + /* 4 */ KEY_H, + /* 5 */ KEY_G, + /* 6 */ KEY_Z, + /* 7 */ KEY_X, + /* 8 */ KEY_C, + /* 9 */ KEY_V, + /* 10 */ KEY_UNKNOWN, /* @ # on french keyboards */ + /* 11 */ KEY_B, + /* 12 */ KEY_Q, + /* 13 */ KEY_W, + /* 14 */ KEY_E, + /* 15 */ KEY_R, + /* 16 */ KEY_Y, + /* 17 */ KEY_T, + /* 18 */ KEY_1, + /* 19 */ KEY_2, + /* 20 */ KEY_3, + /* 21 */ KEY_4, + /* 22 */ KEY_6, + /* 23 */ KEY_5, + /* 24 */ KEY_Equal, + /* 25 */ KEY_9, + /* 26 */ KEY_7, + /* 27 */ KEY_Minus, + /* 28 */ KEY_8, + /* 29 */ KEY_0, + /* 30 */ KEY_RBrace, + /* 31 */ KEY_O, + /* 32 */ KEY_U, + /* 33 */ KEY_LBrace, + /* 34 */ KEY_I, + /* 35 */ KEY_P, + /* 36 */ KEY_Enter, + /* 37 */ KEY_L, + /* 38 */ KEY_J, + /* 39 */ KEY_Quote, + /* 40 */ KEY_K, + /* 41 */ KEY_SemiColon, + /* 42 */ KEY_BSlash, + /* 43 */ KEY_Comma, + /* 44 */ KEY_Slash, + /* 45 */ KEY_N, + /* 46 */ KEY_M, + /* 47 */ KEY_Period, + /* 48 */ KEY_Tab, + /* 49 */ KEY_Space, + /* 50 */ KEY_Tilde, + /* 51 */ KEY_Delete, + /* 52 */ KEY_AltLang, + /* 53 */ KEY_Escape, + /* 54 */ KEY_LCtrl, + /* 55 */ KEY_Alt, + /* 56 */ KEY_ShiftL, + /* 57 */ KEY_CapsLock, + /* 58 */ KEY_LMeta, + /* 59 */ KEY_Left, + /* 60 */ KEY_Right, + /* 61 */ KEY_Down, + /* 62 */ KEY_Up, + /* 63 */ KEY_UNKNOWN, /* Fn */ + /* 64 */ KEY_NOTUSED, + /* 65 */ KEY_KP_Decimal, + /* 66 */ KEY_NOTUSED, + /* 67 */ KEY_KP_Multiply, + /* 68 */ KEY_NOTUSED, + /* 69 */ KEY_KP_Plus, + /* 70 */ KEY_NOTUSED, + /* 71 */ KEY_UNKNOWN, /* Clear */ + /* 72 */ KEY_NOTUSED, + /* 73 */ KEY_NOTUSED, + /* 74 */ KEY_NOTUSED, + /* 75 */ KEY_KP_Divide, + /* 76 */ KEY_KP_Enter, + /* 77 */ KEY_NOTUSED, + /* 78 */ KEY_KP_Minus, + /* 79 */ KEY_NOTUSED, + /* 80 */ KEY_NOTUSED, + /* 81 */ KEY_KP_Equal, /* Keypad = */ + /* 82 */ KEY_KP_0, + /* 83 */ KEY_KP_1, + /* 84 */ KEY_KP_2, + /* 85 */ KEY_KP_3, + /* 86 */ KEY_KP_4, + /* 87 */ KEY_KP_5, + /* 88 */ KEY_KP_6, + /* 89 */ KEY_KP_7, + /* 90 */ KEY_NOTUSED, + /* 91 */ KEY_KP_8, + /* 92 */ KEY_KP_9, + /* 93 */ KEY_NOTUSED, + /* 94 */ KEY_NOTUSED, + /* 95 */ KEY_UNKNOWN, /* Keypad , */ + /* 96 */ KEY_F5, + /* 97 */ KEY_F6, + /* 98 */ KEY_F7, + /* 99 */ KEY_F3, + /* 100 */ KEY_F8, + /* 101 */ KEY_F9, + /* 102 */ KEY_NOTUSED, + /* 103 */ KEY_F11, + /* 104 */ KEY_NOTUSED, + /* 105 */ KEY_NOTUSED, + /* 106 */ KEY_KP_Enter, + /* 107 */ KEY_NOTUSED, + /* 108 */ KEY_NOTUSED, + /* 109 */ KEY_F10, + /* 110 */ KEY_NOTUSED, + /* 111 */ KEY_F12, + /* 112 */ KEY_NOTUSED, + /* 113 */ KEY_NOTUSED, + /* 114 */ KEY_NOTUSED, + /* 115 */ KEY_Home, + /* 116 */ KEY_PgUp, + /* 117 */ KEY_NOTUSED, + /* 118 */ KEY_F4, + /* 119 */ KEY_End, + /* 120 */ KEY_F2, + /* 121 */ KEY_PgDown, + /* 122 */ KEY_F1 +}; +#define WS_ADB_MAP_SIZE (sizeof(wsAdbMap)/sizeof(unsigned char)) + +static +TransMapRec wsAdb = { + 0, + WS_ADB_MAP_SIZE, + wsAdbMap +}; + +static CARD8 wsSunMap[] = { + /* 0x00 */ KEY_NOTUSED, + /* 0x01 */ KEY_NOTUSED, /* stop */ + /* 0x02 */ KEY_NOTUSED, /* BrightnessDown / S-VolumeDown */ + /* 0x03 */ KEY_NOTUSED, /* again */ + /* 0x04 */ KEY_NOTUSED, /* BridgtnessUp / S-VolumeUp */ + /* 0x05 */ KEY_F1, + /* 0x06 */ KEY_F2, + /* 0x07 */ KEY_F10, + /* 0x08 */ KEY_F3, + /* 0x09 */ KEY_F11, + /* 0x0a */ KEY_F4, + /* 0x0b */ KEY_F12, + /* 0x0c */ KEY_F5, + /* 0x0d */ KEY_AltLang, + /* 0x0e */ KEY_F6, + /* 0x0f */ KEY_NOTUSED, + /* 0x10 */ KEY_F7, + /* 0x11 */ KEY_F8, + /* 0x12 */ KEY_F9, + /* 0x13 */ KEY_Alt, + /* 0x14 */ KEY_Up, + /* 0x15 */ KEY_Pause, + /* 0x16 */ KEY_Print, + /* 0x17 */ KEY_NOTUSED, /* props */ + /* 0x18 */ KEY_Left, + /* 0x19 */ KEY_ScrollLock, + /* 0x1a */ KEY_NOTUSED, /* undo */ + /* 0x1b */ KEY_Down, + /* 0x1c */ KEY_Right, + /* 0x1d */ KEY_Escape, + /* 0x1e */ KEY_1, + /* 0x1f */ KEY_2, + /* 0x20 */ KEY_3, + /* 0x21 */ KEY_4, + /* 0x22 */ KEY_5, + /* 0x23 */ KEY_6, + /* 0x24 */ KEY_7, + /* 0x25 */ KEY_8, + /* 0x26 */ KEY_9, + /* 0x27 */ KEY_0, + /* 0x28 */ KEY_Minus, + /* 0x29 */ KEY_Equal, + /* 0x2a */ KEY_Tilde, + /* 0x2b */ KEY_BackSpace, + /* 0x2c */ KEY_Insert, + /* 0x2d */ KEY_KP_Equal, + /* 0x2e */ KEY_KP_Divide, + /* 0x2f */ KEY_KP_Multiply, + /* 0x30 */ KEY_NOTUSED, + /* 0x31 */ KEY_NOTUSED, /* front */ + /* 0x32 */ KEY_KP_Decimal, + /* 0x33 */ KEY_NOTUSED, /* copy */ + /* 0x34 */ KEY_Home, + /* 0x35 */ KEY_Tab, + /* 0x36 */ KEY_Q, + /* 0x37 */ KEY_W, + /* 0x38 */ KEY_E, + /* 0x39 */ KEY_R, + /* 0x3a */ KEY_T, + /* 0x3b */ KEY_Y, + /* 0x3c */ KEY_U, + /* 0x3d */ KEY_I, + /* 0x3e */ KEY_O, + /* 0x3f */ KEY_P, + /* 0x40 */ KEY_LBrace, + /* 0x41 */ KEY_RBrace, + /* 0x42 */ KEY_Delete, + /* 0x43 */ KEY_NOTUSED, /* compose */ + /* 0x44 */ KEY_KP_7, + /* 0x45 */ KEY_KP_8, + /* 0x46 */ KEY_KP_9, + /* 0x47 */ KEY_KP_Minus, + /* 0x48 */ KEY_NOTUSED, /* open */ + /* 0x49 */ KEY_NOTUSED, /* paste */ + /* 0x4a */ KEY_End, + /* 0x4b */ KEY_NOTUSED, + /* 0x4c */ KEY_LCtrl, + /* 0x4d */ KEY_A, + /* 0x4e */ KEY_S, + /* 0x4f */ KEY_D, + /* 0x50 */ KEY_F, + /* 0x51 */ KEY_G, + /* 0x52 */ KEY_H, + /* 0x53 */ KEY_J, + /* 0x54 */ KEY_K, + /* 0x55 */ KEY_L, + /* 0x56 */ KEY_SemiColon, + /* 0x57 */ KEY_Quote, + /* 0x58 */ KEY_BSlash, + /* 0x59 */ KEY_Enter, + /* 0x5a */ KEY_KP_Enter, + /* 0x5b */ KEY_KP_4, + /* 0x5c */ KEY_KP_5, + /* 0x5d */ KEY_KP_6, + /* 0x5e */ KEY_KP_0, + /* 0x5f */ KEY_NOTUSED, /* find */ + /* 0x60 */ KEY_PgUp, + /* 0x61 */ KEY_NOTUSED, /* cut */ + /* 0x62 */ KEY_NumLock, + /* 0x63 */ KEY_ShiftL, + /* 0x64 */ KEY_Z, + /* 0x65 */ KEY_X, + /* 0x66 */ KEY_C, + /* 0x67 */ KEY_V, + /* 0x68 */ KEY_B, + /* 0x69 */ KEY_N, + /* 0x6a */ KEY_M, + /* 0x6b */ KEY_Comma, + /* 0x6c */ KEY_Period, + /* 0x6d */ KEY_Slash, + /* 0x6e */ KEY_ShiftR, + /* 0x6f */ KEY_NOTUSED, /* linefeed */ + /* 0x70 */ KEY_KP_1, + /* 0x71 */ KEY_KP_2, + /* 0x72 */ KEY_KP_3, + /* 0x73 */ KEY_NOTUSED, + /* 0x74 */ KEY_NOTUSED, + /* 0x75 */ KEY_NOTUSED, + /* 0x76 */ KEY_NOTUSED, /* help */ + /* 0x77 */ KEY_CapsLock, + /* 0x78 */ KEY_LMeta, + /* 0x79 */ KEY_Space, + /* 0x7a */ KEY_RMeta, + /* 0x7b */ KEY_PgDown, + /* 0x7c */ KEY_NOTUSED, + /* 0x7d */ KEY_KP_Plus, + /* 0x7e */ KEY_NOTUSED, + /* 0x7f */ KEY_NOTUSED +}; +#define WS_SUN_MAP_SIZE (sizeof(wsSunMap)/sizeof(unsigned char)) + +static +TransMapRec wsSun = { + 0, + WS_SUN_MAP_SIZE, + wsSunMap +}; + +#endif /* WSCONS_SUPPORT */ + +/*ARGSUSED*/ + +/* + * KbdGetMapping -- + * Get the national keyboard mapping. The keyboard type is set, a new map + * and the modifiermap is computed. + */ + +void +KbdGetMapping (InputInfoPtr pInfo, KeySymsPtr pKeySyms, CARD8 *pModMap) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + KeySym *k; + int i; + +#ifndef __bsdi__ + switch (pKbd->consType) { + +#ifdef PCCONS_SUPPORT + case PCCONS: +#if defined(__OpenBSD__) + /* + * on OpenBSD, the pccons keymap is programmable, too + */ + { + pccons_keymap_t keymap[KB_NUM_KEYS]; + if (ioctl(pInfo->fd, CONSOLE_GET_KEYMAP, &keymap) != -1) { + for (i = 0; i < KB_NUM_KEYS; i++) + if (pccons_remap[i]) { + k = map + (pccons_remap[i] << 2); + switch (keymap[i].type) { + case KB_ASCII: + /* For ASCII keys, there is only one char in the keymap */ + k[0] = latin1_to_x[(unsigned char)keymap[i].unshift[0]]; + k[1] = latin1_to_x[(unsigned char)keymap[i].shift[0]]; + k[2] = latin1_to_x[(unsigned char)keymap[i].altgr[0]]; + k[3] = latin1_to_x[(unsigned char)keymap[i].shift_altgr[0]]; + break; + case KB_SCROLL: + k[0] = XK_Scroll_Lock; + goto special; + case KB_NUM: + k[0] = XK_Num_Lock; + goto special; + case KB_CAPS: + k[0] = XK_Caps_Lock; + goto special; + case KB_SHIFT: + switch (keymap[i].unshift[0]) { + case 1: + /* left shift */ + k[0] = XK_Shift_L; + break; + case 2: + /* right shift */ + k[0] = XK_Shift_R; + break; + default: + k[0] = NoSymbol; + } + goto special; + case KB_CTL: + k[0] = XK_Control_L; + goto special; + case KB_ALT: + k[0] = XK_Alt_L; + goto special; + case KB_FUNC: + switch (keymap[i].unshift[2]) { + case 'M': + k[0] = XK_F1; + break; + case 'N': + k[0] = XK_F2; + break; + case 'O': + k[0] = XK_F3; + break; + case 'P': + k[0] = XK_F4; + break; + case 'Q': + k[0] = XK_F5; + break; + case 'R': + k[0] = XK_F6; + break; + case 'S': + k[0] = XK_F7; + break; + case 'T': + k[0] = XK_F8; + break; + case 'U': + k[0] = XK_F9; + break; + case 'V': + k[0] = XK_F10; + break; + case 'W': + k[0] = XK_F11; + break; + case 'X': + k[0] = XK_F12; + break; + default: + k[0] = NoSymbol; + break; + } + goto special; + default: + k[0] = NoSymbol; + special: + k[1] = k[2] = k[3] = NoSymbol; + } + } + } else { + ErrorF("Can't read pccons keymap\n"); + } + } +#endif /* __OpenBSD__ */ + break; +#endif + +/* + * XXX wscons has no GIO_KEYMAP + */ +#if (defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT)) && defined(GIO_KEYMAP) + case SYSCONS: + case PCVT: + { + keymap_t keymap; + + if (ioctl(pInfo->fd, GIO_KEYMAP, &keymap) != -1) { + for (i = 0; i < keymap.n_keys && i < NUM_KEYCODES; i++) + if (remap[i]) { + k = map + (remap[i] << 2); + k[0] = KD_GET_ENTRY(i,0); /* non-shifed */ + k[1] = KD_GET_ENTRY(i,1); /* shifted */ + k[2] = KD_GET_ENTRY(i,4); /* alt */ + k[3] = KD_GET_ENTRY(i,5); /* alt - shifted */ + if (k[3] == k[2]) k[3] = NoSymbol; + if (k[2] == k[1]) k[2] = NoSymbol; + if (k[1] == k[0]) k[1] = NoSymbol; + if (k[0] == k[2] && k[1] == k[3]) + k[2] = k[3] = NoSymbol; + } + } + } + break; +#endif /* SYSCONS || PCVT */ + + } +#endif /* !bsdi */ + + /* + * compute the modifier map + */ + for (i = 0; i < MAP_LENGTH; i++) + pModMap[i] = NoSymbol; /* make sure it is restored */ + + for (k = map, i = MIN_KEYCODE; + i < (NUM_KEYCODES + MIN_KEYCODE); + i++, k += 4) + + switch(*k) { + + case XK_Shift_L: + case XK_Shift_R: + pModMap[i] = ShiftMask; + break; + + case XK_Control_L: + case XK_Control_R: + pModMap[i] = ControlMask; + break; + + case XK_Caps_Lock: + pModMap[i] = LockMask; + break; + + case XK_Alt_L: + case XK_Alt_R: + pModMap[i] = AltMask; + break; + + case XK_Num_Lock: + pModMap[i] = NumLockMask; + break; + + case XK_Scroll_Lock: + pModMap[i] = ScrollLockMask; + break; + + /* kana support */ + case XK_Kana_Lock: + case XK_Kana_Shift: + pModMap[i] = KanaMask; + break; + + /* alternate toggle for multinational support */ + case XK_Mode_switch: + pModMap[i] = AltLangMask; + break; + + } + + pKbd->kbdType = 0; + + pKeySyms->map = map; + pKeySyms->mapWidth = GLYPHS_PER_KEY; + pKeySyms->minKeyCode = MIN_KEYCODE; + pKeySyms->maxKeyCode = MAX_KEYCODE; + + switch(pKbd->consType) { +#ifdef SYSCONS_SUPPORT + case SYSCONS: + if (pKbd->CustomKeycodes) + pKbd->scancodeMap = &sysconsCODE; + else + pKbd->RemapScanCode = ATScancode; + break; +#endif +#if defined(PCCONS_SUPPORT) || defined (PCVT_SUPPORT) + case PCCONS: + case PCVT: + pKbd->RemapScanCode = ATScancode; +#endif +#ifdef WSCONS_SUPPORT + case WSCONS: + switch (pKbd->wsKbdType) { + case WSKBD_TYPE_PC_XT: + case WSKBD_TYPE_PC_AT: + pKbd->RemapScanCode = ATScancode; + break; + case WSKBD_TYPE_USB: + pKbd->scancodeMap = &wsUsb; + break; +#ifdef WSKBD_TYPE_ADB + case WSKBD_TYPE_ADB: + pKbd->scancodeMap = &wsAdb; + break; +#endif +#ifdef WSKBD_TYPE_SUN + case WSKBD_TYPE_SUN: + pKbd->scancodeMap = &wsSun; + break; +#endif + default: + ErrorF("Unknown wskbd type %d\n", pKbd->wsKbdType); + } + break; +#endif + } + return; +} diff --git a/hw/xfree86/os-support/bsd/bsd_apm.c b/hw/xfree86/os-support/bsd/bsd_apm.c new file mode 100644 index 000000000..250e5cb55 --- /dev/null +++ b/hw/xfree86/os-support/bsd/bsd_apm.c @@ -0,0 +1,137 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_apm.c,v 1.1 2000/02/29 03:09:25 dawes Exp $ */ + +#include "X.h" +#include "os.h" +#include "xf86.h" +#include "xf86Priv.h" +#define XF86_OS_PRIVS +#include "xf86_OSproc.h" +#include "xf86_OSlib.h" + +#include <machine/apmvar.h> + +#define APM_DEVICE "/dev/apm" + +static pointer APMihPtr = NULL; +static void bsdCloseAPM(void); + +static struct { + u_int apmBsd; + pmEvent xf86; +} bsdToXF86Array [] = { + { APM_STANDBY_REQ, XF86_APM_SYS_STANDBY }, + { APM_SUSPEND_REQ, XF86_APM_SYS_SUSPEND }, + { APM_NORMAL_RESUME, XF86_APM_NORMAL_RESUME }, + { APM_CRIT_RESUME, XF86_APM_CRITICAL_RESUME }, + { APM_BATTERY_LOW, XF86_APM_LOW_BATTERY }, + { APM_POWER_CHANGE, XF86_APM_POWER_STATUS_CHANGE }, + { APM_UPDATE_TIME, XF86_APM_UPDATE_TIME }, + { APM_CRIT_SUSPEND_REQ, XF86_APM_CRITICAL_SUSPEND }, + { APM_USER_STANDBY_REQ, XF86_APM_USER_STANDBY }, + { APM_USER_SUSPEND_REQ, XF86_APM_USER_SUSPEND }, + { APM_SYS_STANDBY_RESUME, XF86_APM_STANDBY_RESUME }, +#ifdef APM_CAPABILITY_CHANGE + { APM_CAPABILITY_CHANGE, XF86_APM_CAPABILITY_CHANGED }, +#endif +}; + +#define numApmEvents (sizeof(bsdToXF86Array) / sizeof(bsdToXF86Array[0])) + +static pmEvent +bsdToXF86(int type) +{ + int i; + + for (i = 0; i < numApmEvents; i++) { + if (type == bsdToXF86Array[i].apmBsd) { + return bsdToXF86Array[i].xf86; + } + } + return XF86_APM_UNKNOWN; +} + +/* + * APM events can be requested direclty from /dev/apm + */ +static int +bsdPMGetEventFromOS(int fd, pmEvent *events, int num) +{ + struct apm_event_info bsdEvent; + int i; + + for (i = 0; i < num; i++) { + + if (ioctl(fd, APM_IOC_NEXTEVENT, &bsdEvent) < 0) { + if (errno != EAGAIN) { + xf86Msg(X_WARNING, "bsdPMGetEventFromOS: APM_IOC_NEXTEVENT" + " errno = %d\n", errno); + } + break; + } + events[i] = bsdToXF86(bsdEvent.type); + } + return i; +} + +/* + * XXX This won't work on /dev/apm ! + * We should either use /dev/apm_ctl (and kill apmd(8)) + * or talk to apmd (but its protocol is not publically available)... + */ +static pmWait +bsdPMConfirmEventToOs(int fd, pmEvent event) +{ + switch (event) { + case XF86_APM_SYS_STANDBY: + case XF86_APM_USER_STANDBY: + if (ioctl( fd, APM_IOC_STANDBY, NULL ) == 0) + return PM_WAIT; /* should we stop the Xserver in standby, too? */ + else + return PM_NONE; + case XF86_APM_SYS_SUSPEND: + case XF86_APM_CRITICAL_SUSPEND: + case XF86_APM_USER_SUSPEND: + if (ioctl( fd, APM_IOC_SUSPEND, NULL ) == 0) + return PM_WAIT; + else + return PM_NONE; + case XF86_APM_STANDBY_RESUME: + case XF86_APM_NORMAL_RESUME: + case XF86_APM_CRITICAL_RESUME: + case XF86_APM_STANDBY_FAILED: + case XF86_APM_SUSPEND_FAILED: + return PM_CONTINUE; + default: + return PM_NONE; + } +} + +PMClose +xf86OSPMOpen(void) +{ + int fd; + + if (APMihPtr || !xf86Info.pmFlag) { + return NULL; + } + + if ((fd = open(APM_DEVICE, O_RDWR)) == -1) { + return NULL; + } + xf86PMGetEventFromOs = bsdPMGetEventFromOS; + xf86PMConfirmEventToOs = bsdPMConfirmEventToOs; + APMihPtr = xf86AddInputHandler(fd, xf86HandlePMEvents, NULL); + return bsdCloseAPM; +} + +static void +bsdCloseAPM(void) +{ + int fd; + + if (APMihPtr) { + fd = xf86RemoveInputHandler(APMihPtr); + close(fd); + APMihPtr = NULL; + } +} diff --git a/hw/xfree86/os-support/bsd/bsd_axp.c b/hw/xfree86/os-support/bsd/bsd_axp.c new file mode 100644 index 000000000..c38ac073c --- /dev/null +++ b/hw/xfree86/os-support/bsd/bsd_axp.c @@ -0,0 +1,69 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_axp.c,v 1.2 2002/10/29 23:19:13 herrb Exp $ */ + +#include "X.h" +#include "os.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86Axp.h" +#include <sys/param.h> +#include "xf86_OSlib.h" +#include <stdio.h> +#include <sys/sysctl.h> + +axpDevice bsdGetAXP(void); + +/* + * BSD does a very nice job providing system information to + * user space programs. Unfortunately it doesn't provide all + * the information required. Therefore we just obtain the + * system type and look up the rest from a list we maintain + * ourselves. + */ + +typedef struct { + char *name; + int type; +} AXP; + +static AXP axpList[] = { + {"apecs",APECS}, + {"pyxis",PYXIS}, + {"cia",CIA}, + {"irongate",IRONGATE}, + {"lca",LCA}, + {"t2",T2}, + {"tsunami",TSUNAMI}, + {NULL,NONE} +}; + +axpDevice +bsdGetAXP(void) +{ + int i; + char sysname[64]; + size_t len = sizeof(sysname); + +#ifdef __OpenBSD__ + int mib[3]; + int error; + + mib[0] = CTL_MACHDEP; + mib[1] = CPU_CHIPSET; + mib[2] = CPU_CHIPSET_TYPE; + + if ((error = sysctl(mib, 3, &sysname, &len, NULL, 0)) < 0) +#else + if ((sysctlbyname("hw.chipset.type", &sysname, &len, + 0, 0)) < 0) +#endif + FatalError("bsdGetAXP: can't find machine type\n"); +#ifdef DEBUG + xf86Msg(X_INFO,"AXP is a: %s\n",sysname); +#endif + for (i=0;;i++) { + if (axpList[i].name == NULL) + return NONE; + if (!strcmp(sysname, axpList[i].name)) + return axpList[i].type; + } +} diff --git a/hw/xfree86/os-support/bsd/bsd_ev56.c b/hw/xfree86/os-support/bsd/bsd_ev56.c new file mode 100644 index 000000000..ec95306e8 --- /dev/null +++ b/hw/xfree86/os-support/bsd/bsd_ev56.c @@ -0,0 +1,87 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_ev56.c,v 1.2 2001/02/27 23:05:00 alanh Exp $ */ + +#include "X.h" +#include "input.h" +#include "scrnintstr.h" +#include "compiler.h" + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "xf86OSpriv.h" + +int readDense8(pointer Base, register unsigned long Offset); +int readDense16(pointer Base, register unsigned long Offset); +int readDense32(pointer Base, register unsigned long Offset); +void +writeDenseNB8(int Value, pointer Base, register unsigned long Offset); +void +writeDenseNB16(int Value, pointer Base, register unsigned long Offset); +void +writeDenseNB32(int Value, pointer Base, register unsigned long Offset); +void +writeDense8(int Value, pointer Base, register unsigned long Offset); +void +writeDense16(int Value, pointer Base, register unsigned long Offset); +void +writeDense32(int Value, pointer Base, register unsigned long Offset); + +int +readDense8(pointer Base, register unsigned long Offset) +{ + mem_barrier(); + return *(volatile CARD8*) ((unsigned long)Base+(Offset)); +} + +int +readDense16(pointer Base, register unsigned long Offset) +{ + mem_barrier(); + return *(volatile CARD16*) ((unsigned long)Base+(Offset)); +} + +int +readDense32(pointer Base, register unsigned long Offset) +{ + mem_barrier(); + return *(volatile CARD32*)((unsigned long)Base+(Offset)); +} + +void +writeDenseNB8(int Value, pointer Base, register unsigned long Offset) +{ + *(volatile CARD8*)((unsigned long)Base+(Offset)) = Value; +} + +void +writeDenseNB16(int Value, pointer Base, register unsigned long Offset) +{ + *(volatile CARD16*)((unsigned long)Base + (Offset)) = Value; +} + +void +writeDenseNB32(int Value, pointer Base, register unsigned long Offset) +{ + *(volatile CARD32*)((unsigned long)Base+(Offset)) = Value; +} + +void +writeDense8(int Value, pointer Base, register unsigned long Offset) +{ + write_mem_barrier(); + *(volatile CARD8 *)((unsigned long)Base+(Offset)) = Value; +} + +void +writeDense16(int Value, pointer Base, register unsigned long Offset) +{ + write_mem_barrier(); + *(volatile CARD16 *)((unsigned long)Base+(Offset)) = Value; +} + +void +writeDense32(int Value, pointer Base, register unsigned long Offset) +{ + write_mem_barrier(); + *(volatile CARD32 *)((unsigned long)Base+(Offset)) = Value; +} diff --git a/hw/xfree86/os-support/bsd/bsd_kbd.c b/hw/xfree86/os-support/bsd/bsd_kbd.c new file mode 100644 index 000000000..20d8b04d4 --- /dev/null +++ b/hw/xfree86/os-support/bsd/bsd_kbd.c @@ -0,0 +1,536 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_kbd.c,v 1.5 2003/02/17 15:11:56 dawes Exp $ */ + +/* + * Copyright (c) 2002 by The XFree86 Project, Inc. + * Author: Ivan Pascal. + * + * Based on the code from bsd_io.c which is + * Copyright 1992 by Rich Murphey <Rich@Rice.edu> + * Copyright 1993 by David Dawes <dawes@xfree86.org> + */ + +#define NEED_EVENTS +#include "X.h" + +#include "compiler.h" + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +#include "xf86Xinput.h" +#include "xf86OSKbd.h" +#include "atKeynames.h" +#include "bsd_kbd.h" + +extern Bool VTSwitchEnabled; +#ifdef USE_VT_SYSREQ +extern Bool VTSysreqToggle; +#endif + +static KbdProtocolRec protocols[] = { + {"standard", PROT_STD }, +#ifdef WSCONS_SUPPORT + {"wskbd", PROT_WSCONS }, +#endif + { NULL, PROT_UNKNOWN } +}; + +typedef struct { + struct termio kbdtty; +} BsdKbdPrivRec, *BsdKbdPrivPtr; + +static +int KbdInit(InputInfoPtr pInfo, int what) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + BsdKbdPrivPtr priv = (BsdKbdPrivPtr) pKbd->private; + + if (pKbd->isConsole) { + switch (pKbd->consType) { +#if defined(PCCONS_SUPPORT) || defined(SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) || defined (WSCONS_SUPPORT) + case PCCONS: + case SYSCONS: + case PCVT: +#if defined WSCONS_SUPPORT + case WSCONS: +#endif + tcgetattr(pInfo->fd, &(priv->kbdtty)); +#endif + break; + } + } + + return Success; +} + +static void +SetKbdLeds(InputInfoPtr pInfo, int leds) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + int real_leds = 0; + + if (leds & XLED1) real_leds |= LED_CAP; + if (leds & XLED2) real_leds |= LED_NUM; + if (leds & XLED3) real_leds |= LED_SCR; + if (leds & XLED4) real_leds |= LED_SCR; + + switch (pKbd->consType) { + + case PCCONS: + break; +#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) + case SYSCONS: + case PCVT: + ioctl(pInfo->fd, KDSETLED, real_leds); + break; +#endif +#if defined(WSCONS_SUPPORT) + case WSCONS: + ioctl(pInfo->fd, WSKBDIO_SETLEDS, &real_leds); + break; +#endif + } +} + +static int +GetKbdLeds(InputInfoPtr pInfo) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + int leds = 0, real_leds = 0; + + switch (pKbd->consType) { + case PCCONS: + break; +#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) + case SYSCONS: + case PCVT: + ioctl(pInfo->fd, KDGETLED, &real_leds); + break; +#endif +#if defined(WSCONS_SUPPORT) + case WSCONS: + ioctl(pInfo->fd, WSKBDIO_GETLEDS, &real_leds); + break; +#endif + } + + if (real_leds & LED_CAP) leds |= XLED1; + if (real_leds & LED_NUM) leds |= XLED2; + if (real_leds & LED_SCR) leds |= XLED3; + + return(leds); +} + +static void +SetKbdRepeat(InputInfoPtr pInfo, char rad) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + switch (pKbd->consType) { + + case PCCONS: + break; +#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) + case SYSCONS: + case PCVT: + ioctl(pInfo->fd, KDSETRAD, rad); + break; +#endif + } +} + +static int +KbdOn(InputInfoPtr pInfo, int what) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + BsdKbdPrivPtr priv = (BsdKbdPrivPtr) pKbd->private; + struct termios nTty; +#ifdef WSCONS_SUPPORT + int option; +#endif + + if (pKbd->isConsole) { + switch (pKbd->consType) { + +#if defined(SYSCONS_SUPPORT) || defined(PCCONS_SUPPORT) || defined(PCVT_SUPPORT) + case SYSCONS: + case PCCONS: + case PCVT: +#ifdef WSCONS_SUPPORT + case WSCONS: +#endif + nTty = priv->kbdtty; + nTty.c_iflag = IGNPAR | IGNBRK; + nTty.c_oflag = 0; + nTty.c_cflag = CREAD | CS8; + nTty.c_lflag = 0; + nTty.c_cc[VTIME] = 0; + nTty.c_cc[VMIN] = 1; + cfsetispeed(&nTty, 9600); + cfsetospeed(&nTty, 9600); + tcsetattr(pInfo->fd, TCSANOW, &nTty); + break; +#endif + } +#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) || defined (WSCONS_SUPPORT) + switch (pKbd->consType) { + case SYSCONS: + case PCVT: +#ifdef K_CODE + if (pKbd->CustomKeycodes) + ioctl(pInfo->fd, KDSKBMODE, K_CODE); + else + ioctl(pInfo->fd, KDSKBMODE, K_RAW); +#else + ioctl(pInfo->fd, KDSKBMODE, K_RAW); +#endif + break; +#endif +#ifdef WSCONS_SUPPORT + case WSCONS: + option = WSKBD_RAW; + if (ioctl(pInfo->fd, WSKBDIO_SETMODE, &option) == -1) { + FatalError("can't switch keyboard to raw mode. " + "Enable support for it in the kernel\n" + "or use for example:\n\n" + "Option \"Protocol\" \"wskbd\"\n" + "Option \"Device\" \"/dev/wskbd0\"\n" + "\nin your XF86Config(5) file\n"); + } + break; +#endif + } + } + return Success; +} + +static int +KbdOff(InputInfoPtr pInfo, int what) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + BsdKbdPrivPtr priv = (BsdKbdPrivPtr) pKbd->private; +#ifdef WSCONS_SUPPORT + int option; +#endif + + if (pKbd->isConsole) { + switch (pKbd->consType) { +#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) + case SYSCONS: + case PCVT: + ioctl(pInfo->fd, KDSKBMODE, K_XLATE); + /* FALL THROUGH */ +#endif +#if defined(SYSCONS_SUPPORT) || defined(PCCONS_SUPPORT) || defined(PCVT_SUPPORT) + case PCCONS: + tcsetattr(pInfo->fd, TCSANOW, &(priv->kbdtty)); + break; +#endif +#ifdef WSCONS_SUPPORT + case WSCONS: + option = WSKBD_TRANSLATED; + ioctl(xf86Info.consoleFd, WSKBDIO_SETMODE, &option); + tcsetattr(xf86Info.consoleFd, TCSANOW, &(priv->kbdtty)); + break; +#endif + } + } + return Success; +} + +static void +SoundBell(InputInfoPtr pInfo, int loudness, int pitch, int duration) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; +#ifdef WSCONS_SUPPORT + struct wskbd_bell_data wsb; +#endif + + if (loudness && pitch) { + switch (pKbd->consType) { +#ifdef PCCONS_SUPPORT + case PCCONS: + { int data[2]; + data[0] = pitch; + data[1] = (duration * loudness) / 50; + ioctl(pInfo->fd, CONSOLE_X_BELL, data); + break; + } +#endif +#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) + case SYSCONS: + case PCVT: + ioctl(pInfo->fd, KDMKTONE, + ((1193190 / pitch) & 0xffff) | + (((unsigned long)duration*loudness/50)<<16)); + break; +#endif +#if defined (WSCONS_SUPPORT) + case WSCONS: + wsb.which = WSKBD_BELL_DOALL; + wsb.pitch = pitch; + wsb.period = duration; + wsb.volume = loudness; + ioctl(pInfo->fd, WSKBDIO_COMPLEXBELL, &wsb); + break; +#endif + } + } +} + +#define ModifierSet(k) ((modifiers & (k)) == (k)) + +static +Bool SpecialKey(InputInfoPtr pInfo, int key, Bool down, int modifiers) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + + if(!pKbd->vtSwitchSupported) + return FALSE; + + if ((ModifierSet(ControlMask | AltMask)) || + (ModifierSet(ControlMask | AltLangMask))) { + if (VTSwitchEnabled && !xf86Info.vtSysreq) { + switch (key) { + case KEY_F1: + case KEY_F2: + case KEY_F3: + case KEY_F4: + case KEY_F5: + case KEY_F6: + case KEY_F7: + case KEY_F8: + case KEY_F9: + case KEY_F10: + if (down) { + ioctl(xf86Info.consoleFd, VT_ACTIVATE, key - KEY_F1 + 1); + return TRUE; + } + case KEY_F11: + case KEY_F12: + if (down) { + ioctl(xf86Info.consoleFd, VT_ACTIVATE, key - KEY_F11 + 11); + return TRUE; + } + } + } + } +#ifdef USE_VT_SYSREQ + if (VTSwitchEnabled && xf86Info.vtSysreq) { + switch (key) { + case KEY_F1: + case KEY_F2: + case KEY_F3: + case KEY_F4: + case KEY_F5: + case KEY_F6: + case KEY_F7: + case KEY_F8: + case KEY_F9: + case KEY_F10: + if (VTSysreqToggle && down) { + ioctl(xf86Info.consoleFd, VT_ACTIVATE, key - KEY_F1 + 1); + VTSysreqToggle = FALSE; + return TRUE; + } + break; + case KEY_F11: + case KEY_F12: + if (VTSysreqToggle && down) { + ioctl(xf86Info.consoleFd, VT_ACTIVATE, key - KEY_F11 + 11); + VTSysreqToggle = FALSE; + return TRUE; + } + break; + /* Ignore these keys -- ie don't let them cancel an alt-sysreq */ + case KEY_Alt: + case KEY_AltLang: + break; + case KEY_SysReqest: + if ((ModifierSet(AltMask) || ModifierSet(AltLangMask)) && down) + VTSysreqToggle = TRUE; + break; + default: + /* + * We only land here when Alt-SysReq is followed by a + * non-switching key. + */ + if (VTSysreqToggle) + VTSysreqToggle = FALSE; + } + } +#endif /* USE_VT_SYSREQ */ + + return FALSE; +} + +static void +stdReadInput(InputInfoPtr pInfo) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + unsigned char rBuf[64]; + int nBytes, i; + if ((nBytes = read( pInfo->fd, (char *)rBuf, sizeof(rBuf))) > 0) { + for (i = 0; i < nBytes; i++) + pKbd->PostEvent(pInfo, rBuf[i] & 0x7f, + rBuf[i] & 0x80 ? FALSE : TRUE); + } +} + +#ifdef WSCONS_SUPPORT +static void +WSReadInput(InputInfoPtr pInfo) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + struct wscons_event events[64]; + int n, i; + if ((n = read( pInfo->fd, events, sizeof(events))) > 0) { + n /= sizeof(struct wscons_event); + for (i = 0; i < n; i++) + pKbd->PostEvent(pInfo, events[i].value, + events[i].type == WSCONS_EVENT_KEY_DOWN ? TRUE : FALSE); + } +} +#endif + +#ifdef WSCONS_SUPPORT +static void +printWsType(char *type, char *devname) +{ + xf86Msg(X_PROBED, "%s: Keyboard type: %s\n", type, devname); +} +#endif + +static Bool +OpenKeyboard(InputInfoPtr pInfo) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + int i; + KbdProtocolId prot = PROT_UNKNOWN; + char *s; + + s = xf86SetStrOption(pInfo->options, "Protocol", NULL); + for (i = 0; protocols[i].name; i++) { + if (xf86NameCmp(s, protocols[i].name) == 0) { + prot = protocols[i].id; + break; + } + } + + switch (prot) { + case PROT_STD: + pInfo->read_input = stdReadInput; + break; +#ifdef WSCONS_SUPPORT + case PROT_WSCONS: + pInfo->read_input = WSReadInput; + break; +#endif + default: + xf86Msg(X_ERROR,"\"%s\" is not a valid keyboard protocol name\n", s); + xfree(s); + return FALSE; + } + xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, s); + xfree(s); + + s = xf86SetStrOption(pInfo->options, "Device", NULL); + if (s == NULL) { + if (prot == PROT_WSCONS) { + xf86Msg(X_ERROR,"A \"device\" option is required with" + " the \"wskbd\" keyboard protocol\n"); + return FALSE; + } else { + pInfo->fd = xf86Info.consoleFd; + pKbd->isConsole = TRUE; + pKbd->consType = xf86Info.consType; + } + } else { + pInfo->fd = open(s, O_RDONLY | O_NONBLOCK | O_EXCL); + if (pInfo->fd == -1) { + xf86Msg(X_ERROR, "%s: cannot open \"%s\"\n", pInfo->name, s); + xfree(s); + return FALSE; + } + pKbd->isConsole = FALSE; + /* XXX What is consType here? */ + pKbd->consType = SYSCONS; + xfree(s); + } + +#if defined (SYSCONS_SUPPORT) || defined (PCVT_SUPPORT) + if (pKbd->isConsole && + ((pKbd->consType == SYSCONS) || (pKbd->consType == PCVT))) + pKbd->vtSwitchSupported = TRUE; +#endif + +#ifdef WSCONS_SUPPORT + if( prot == PROT_WSCONS) { + pKbd->consType = WSCONS; + /* Find out keyboard type */ + if (ioctl(pInfo->fd, WSKBDIO_GTYPE, &(pKbd->wsKbdType)) == -1) { + xf86Msg(X_ERROR, "%s: cannot get keyboard type", pInfo->name); + close(pInfo->fd); + return FALSE; + } + switch (pKbd->wsKbdType) { + case WSKBD_TYPE_PC_XT: + printWsType("XT", pInfo->name); + break; + case WSKBD_TYPE_PC_AT: + printWsType("AT", pInfo->name); + break; + case WSKBD_TYPE_USB: + printWsType("USB", pInfo->name); + break; +#ifdef WSKBD_TYPE_ADB + case WSKBD_TYPE_ADB: + printWsType("ADB", pInfo->name); + break; +#endif +#ifdef WSKBD_TYPE_SUN + case WSKBD_TYPE_SUN: + printWsType("Sun", pInfo->name); + break; +#endif + default: + xf86Msg(X_ERROR, "%s: Unsupported wskbd type \"%d\"", + pKbd->wsKbdType, pInfo->name); + close(pInfo->fd); + return FALSE; + } + } +#endif + return TRUE; +} + +Bool +xf86OSKbdPreInit(InputInfoPtr pInfo) +{ + KbdDevPtr pKbd = pInfo->private; + + pKbd->KbdInit = KbdInit; + pKbd->KbdOn = KbdOn; + pKbd->KbdOff = KbdOff; + pKbd->Bell = SoundBell; + pKbd->SetLeds = SetKbdLeds; + pKbd->GetLeds = GetKbdLeds; + pKbd->SetKbdRepeat = SetKbdRepeat; + pKbd->KbdGetMapping = KbdGetMapping; + pKbd->SpecialKey = SpecialKey; + + pKbd->RemapScanCode = NULL; + pKbd->GetSpecialKey = NULL; + + pKbd->OpenKeyboard = OpenKeyboard; + pKbd->vtSwitchSupported = FALSE; + pKbd->CustomKeycodes = FALSE; + + pKbd->private = xcalloc(sizeof(BsdKbdPrivRec), 1); + if (pKbd->private == NULL) { + xf86Msg(X_ERROR,"can't allocate keyboard OS private data\n"); + return FALSE; + } + return TRUE; +} + diff --git a/hw/xfree86/os-support/bsd/bsd_kbd.h b/hw/xfree86/os-support/bsd/bsd_kbd.h new file mode 100644 index 000000000..c042d88bf --- /dev/null +++ b/hw/xfree86/os-support/bsd/bsd_kbd.h @@ -0,0 +1,5 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_kbd.h,v 1.1 2002/10/11 01:40:34 dawes Exp $ */ + +extern void KbdGetMapping(InputInfoPtr pInfo, KeySymsPtr pKeySyms, + CARD8 *pModMap); + diff --git a/hw/xfree86/os-support/bsd/bsd_kmod.c b/hw/xfree86/os-support/bsd/bsd_kmod.c new file mode 100644 index 000000000..74345654b --- /dev/null +++ b/hw/xfree86/os-support/bsd/bsd_kmod.c @@ -0,0 +1,27 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_kmod.c,v 3.2 2002/11/29 17:47:24 tsi Exp $ */ + +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/param.h> +#include <sys/linker.h> + +#include "xf86_OSproc.h" +#include "xf86_ansic.h" + +/* + * Load a FreeBSD kernel module. + * This is used by the DRI/DRM to load a DRM kernel module when + * the X server starts. It could be used for other purposes in the future. + * Input: + * modName - name of the kernel module (Ex: "tdfx") + * Return: + * 0 for failure, 1 for success + */ +int xf86LoadKernelModule(const char *modName) +{ + if (kldload(modName) != -1) + return 1; + else + return 0; +} diff --git a/hw/xfree86/os-support/bsd/bsd_kqueue_apm.c b/hw/xfree86/os-support/bsd/bsd_kqueue_apm.c new file mode 100644 index 000000000..53fe8c3be --- /dev/null +++ b/hw/xfree86/os-support/bsd/bsd_kqueue_apm.c @@ -0,0 +1,199 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_kqueue_apm.c,v 1.5 2002/07/30 23:24:32 herrb Exp $ */ +/* + * Copyright (C) 2001 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. + * IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES + * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR + * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR + * THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from the XFree86 Project. + */ +/* $OpenBSD: bsd_kqueue_apm.c,v 1.5 2002/07/30 23:07:42 matthieu Exp $ */ + +#include "X.h" +#include "os.h" +#include "xf86.h" +#include "xf86Priv.h" +#define XF86_OS_PRIVS +#include "xf86_OSproc.h" +#include "xf86_OSlib.h" + +#include <sys/event.h> +#include <machine/apmvar.h> + +#define _PATH_APM_SOCKET "/var/run/apmdev" +#define _PATH_APM_DEV "/dev/apm" +#define _PATH_APM_CTLDEV "/dev/apmctl" + +static pointer APMihPtr = NULL; +static int devFd = -1; +static int ctlFd = -1; +static void bsdCloseAPM(void); + +static struct { + u_int apmBsd; + pmEvent xf86; +} bsdToXF86Array [] = { + { APM_STANDBY_REQ, XF86_APM_SYS_STANDBY }, + { APM_SUSPEND_REQ, XF86_APM_SYS_SUSPEND }, + { APM_NORMAL_RESUME, XF86_APM_NORMAL_RESUME }, + { APM_CRIT_RESUME, XF86_APM_CRITICAL_RESUME }, + { APM_BATTERY_LOW, XF86_APM_LOW_BATTERY }, + { APM_POWER_CHANGE, XF86_APM_POWER_STATUS_CHANGE }, + { APM_UPDATE_TIME, XF86_APM_UPDATE_TIME }, + { APM_CRIT_SUSPEND_REQ, XF86_APM_CRITICAL_SUSPEND }, + { APM_USER_STANDBY_REQ, XF86_APM_USER_STANDBY }, + { APM_USER_SUSPEND_REQ, XF86_APM_USER_SUSPEND }, + { APM_SYS_STANDBY_RESUME, XF86_APM_STANDBY_RESUME }, +#ifdef APM_CAPABILITY_CHANGE + { APM_CAPABILITY_CHANGE, XF86_APM_CAPABILITY_CHANGED }, +#endif +}; + +#define numApmEvents (sizeof(bsdToXF86Array) / sizeof(bsdToXF86Array[0])) + +static pmEvent +bsdToXF86(int type) +{ + int i; + + for (i = 0; i < numApmEvents; i++) { + if (type == bsdToXF86Array[i].apmBsd) { + return bsdToXF86Array[i].xf86; + } + } + return XF86_APM_UNKNOWN; +} + +/* + * APM events can be requested direclty from /dev/apm + */ +static int +bsdPMGetEventFromOS(int kq, pmEvent *events, int num) +{ + struct kevent ev; + int i, result; + struct timespec ts = { 0, 0 }; + + for (i = 0; i < num; i++) { + result = kevent(kq, NULL, 0, &ev, 1, &ts); + if (result == 0 || APM_EVENT_TYPE(ev.data) == APM_NOEVENT) { + /* no event */ + break; + } else if (result < 0) { + xf86Msg(X_WARNING, "bsdPMGetEventFromOS: kevent returns" + " errno = %d\n", errno); + break; + } + events[i] = bsdToXF86(APM_EVENT_TYPE(ev.data)); + } + return i; +} + +/* + * If apmd(8) is running, he will get the events and handle them, + * so, we've nothing to do here. + * Otherwise, opening /dev/apmctl will succeed and we have to send the + * confirmations to /dev/apmctl. + */ +static pmWait +bsdPMConfirmEventToOs(int dummyfd, pmEvent event) +{ + if (ctlFd < 0) { + if ((ctlFd = open(_PATH_APM_CTLDEV, O_RDWR)) < 0) { + return PM_NONE; + } + } + /* apmctl open succeedeed */ + switch (event) { + case XF86_APM_SYS_STANDBY: + case XF86_APM_USER_STANDBY: + if (ioctl( ctlFd, APM_IOC_STANDBY, NULL ) == 0) + return PM_WAIT; /* should we stop the Xserver in standby, too? */ + else + return PM_NONE; + + case XF86_APM_SYS_SUSPEND: + case XF86_APM_CRITICAL_SUSPEND: + case XF86_APM_USER_SUSPEND: + if (ioctl( ctlFd, APM_IOC_SUSPEND, NULL ) == 0) + return PM_WAIT; + else + return PM_NONE; + break; + case XF86_APM_STANDBY_RESUME: + case XF86_APM_NORMAL_RESUME: + case XF86_APM_CRITICAL_RESUME: + case XF86_APM_STANDBY_FAILED: + case XF86_APM_SUSPEND_FAILED: + return PM_CONTINUE; + break; + default: + return PM_NONE; + } +} + +PMClose +xf86OSPMOpen(void) +{ + int kq; + struct kevent ev; + + if (APMihPtr || !xf86Info.pmFlag) { + return NULL; + } + if ((devFd = open(_PATH_APM_DEV, O_RDONLY)) == -1) { + return NULL; + } + if ((kq = kqueue()) <= 0) { + close(devFd); + return NULL; + } + EV_SET(&ev, devFd, EVFILT_READ, EV_ADD | EV_ENABLE | EV_CLEAR, + 0, 0, NULL); + if (kevent(kq, &ev, 1, NULL, 0, NULL) < 0) { + close(devFd); + return NULL; + } + + xf86PMGetEventFromOs = bsdPMGetEventFromOS; + xf86PMConfirmEventToOs = bsdPMConfirmEventToOs; + APMihPtr = xf86AddInputHandler(kq, xf86HandlePMEvents, NULL); + return bsdCloseAPM; +} + +static void +bsdCloseAPM(void) +{ + int kq; + + if (APMihPtr) { + kq = xf86RemoveInputHandler(APMihPtr); + close(devFd); + devFd = -1; + close(kq); + if (ctlFd >= 0) { + close(ctlFd); + ctlFd = -1; + } + APMihPtr = NULL; + } +} diff --git a/hw/xfree86/os-support/bsd/bsd_mouse.c b/hw/xfree86/os-support/bsd/bsd_mouse.c new file mode 100644 index 000000000..f681d90d9 --- /dev/null +++ b/hw/xfree86/os-support/bsd/bsd_mouse.c @@ -0,0 +1,594 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/bsd_mouse.c,v 1.24 2003/02/15 05:37:59 paulo Exp $ */ + +/* + * Copyright 1999 by The XFree86 Project, Inc. + */ + +#include "X.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "xf86Xinput.h" +#include "xf86OSmouse.h" +#include "xisb.h" +#include "mipointer.h" +#ifdef WSCONS_SUPPORT +#include <dev/wscons/wsconsio.h> +#endif +#ifdef USBMOUSE_SUPPORT +#ifdef HAS_LIB_USB_HID +#include <usbhid.h> +#else +#include "usb.h" +#endif + +#include <dev/usb/usb.h> +#ifdef USB_GET_REPORT_ID +#define USB_NEW_HID +#endif + +#define HUP_GENERIC_DESKTOP 0x0001 +#define HUP_BUTTON 0x0009 + +#define HUG_X 0x0030 +#define HUG_Y 0x0031 +#define HUG_Z 0x0032 +#define HUG_WHEEL 0x0038 + +#define HID_USAGE2(p,u) (((p) << 16) | u) + +/* The UMS mices have middle button as number 3 */ +#define UMS_BUT(i) ((i) == 0 ? 2 : (i) == 1 ? 0 : (i) == 2 ? 1 : (i)) +#endif /* USBMOUSE_SUPPORT */ + +#ifdef USBMOUSE_SUPPORT +static void usbSigioReadInput (int fd, void *closure); +#endif + +static int +SupportedInterfaces(void) +{ +#if defined(__NetBSD__) + return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO; +#elif defined(__FreeBSD__) + return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO | MSE_MISC; +#else + return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO; +#endif +} + +/* Names of protocols that are handled internally here. */ +static const char *internalNames[] = { +#if defined(WSCONS_SUPPORT) + "WSMouse", +#endif +#if defined(USBMOUSE_SUPPORT) + "usb", +#endif + NULL +}; + +/* + * Names of MSC_MISC protocols that the OS supports. These are decoded by + * main "mouse" driver. + */ +static const char *miscNames[] = { +#if defined(__FreeBSD__) + "SysMouse", +#endif + 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; + for (i = 0; miscNames[i]; i++) + if (xf86NameCmp(protocol, miscNames[i]) == 0) + return TRUE; + return FALSE; +} + +static const char * +DefaultProtocol(void) +{ +#if defined(__FreeBSD__) + return "Auto"; +#else + return NULL; +#endif +} + +#if defined(__FreeBSD__) && defined(MOUSE_PROTO_SYSMOUSE) +static struct { + int dproto; + const char *name; +} devproto[] = { + { MOUSE_PROTO_MS, "Microsoft" }, + { MOUSE_PROTO_MSC, "MouseSystems" }, + { MOUSE_PROTO_LOGI, "Logitech" }, + { MOUSE_PROTO_MM, "MMSeries" }, + { MOUSE_PROTO_LOGIMOUSEMAN, "MouseMan" }, + { MOUSE_PROTO_BUS, "BusMouse" }, + { MOUSE_PROTO_INPORT, "BusMouse" }, + { MOUSE_PROTO_PS2, "PS/2" }, + { MOUSE_PROTO_HITTAB, "MMHitTab" }, + { MOUSE_PROTO_GLIDEPOINT, "GlidePoint" }, + { MOUSE_PROTO_INTELLI, "Intellimouse" }, + { MOUSE_PROTO_THINK, "ThinkingMouse" }, + { MOUSE_PROTO_SYSMOUSE, "SysMouse" } +}; + +static const char * +SetupAuto(InputInfoPtr pInfo, int *protoPara) +{ + int i; + mousehw_t hw; + mousemode_t mode; + + if (pInfo->fd == -1) + return NULL; + + /* set the driver operation level, if applicable */ + i = 1; + ioctl(pInfo->fd, MOUSE_SETLEVEL, &i); + + /* interrogate the driver and get some intelligence on the device. */ + hw.iftype = MOUSE_IF_UNKNOWN; + hw.model = MOUSE_MODEL_GENERIC; + ioctl(pInfo->fd, MOUSE_GETHWINFO, &hw); + xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: hw.iftype is %d, hw.model is %d\n", + pInfo->name, hw.iftype, hw.model); + if (ioctl(pInfo->fd, MOUSE_GETMODE, &mode) == 0) { + for (i = 0; i < sizeof(devproto)/sizeof(devproto[0]); ++i) { + if (mode.protocol == devproto[i].dproto) { + /* override some parameters */ + if (protoPara) { + protoPara[4] = mode.packetsize; + protoPara[0] = mode.syncmask[0]; + protoPara[1] = mode.syncmask[1]; + } + xf86MsgVerb(X_INFO, 3, "%s: SetupAuto: protocol is %s\n", + pInfo->name, devproto[i].name); + return devproto[i].name; + } + } + } + return NULL; +} + +static void +SetSysMouseRes(InputInfoPtr pInfo, const char *protocol, int rate, int res) +{ + mousemode_t mode; + MouseDevPtr pMse; + + pMse = pInfo->private; + + mode.rate = rate > 0 ? rate : -1; + mode.resolution = res > 0 ? res : -1; + mode.accelfactor = -1; +#if defined(__FreeBSD__) + if (pMse->autoProbe || + (protocol && xf86NameCmp(protocol, "SysMouse") == 0)) { + /* + * As the FreeBSD sysmouse driver defaults to protocol level 0 + * everytime it is opened we enforce protocol level 1 again at + * this point. + */ + mode.level = 1; + } else + mode.level = -1; +#else + mode.level = -1; +#endif + ioctl(pInfo->fd, MOUSE_SETMODE, &mode); +} +#endif + +#if defined(WSCONS_SUPPORT) +#define NUMEVENTS 64 + +static void +wsconsReadInput(InputInfoPtr pInfo) +{ + MouseDevPtr pMse; + static struct wscons_event eventList[NUMEVENTS]; + int n, c; + struct wscons_event *event = eventList; + unsigned char *pBuf; + + pMse = pInfo->private; + + XisbBlockDuration(pMse->buffer, -1); + pBuf = (unsigned char *)eventList; + n = 0; + while ((c = XisbRead(pMse->buffer)) >= 0 && n < sizeof(eventList)) { + pBuf[n++] = (unsigned char)c; + } + + if (n == 0) + return; + + n /= sizeof(struct wscons_event); + while( n-- ) { + int buttons = pMse->lastButtons; + int dx = 0, dy = 0, dz = 0, dw = 0; + switch (event->type) { + case WSCONS_EVENT_MOUSE_UP: +#define BUTBIT (1 << (event->value <= 2 ? 2 - event->value : event->value)) + buttons &= ~BUTBIT; + break; + case WSCONS_EVENT_MOUSE_DOWN: + buttons |= BUTBIT; + break; + case WSCONS_EVENT_MOUSE_DELTA_X: + dx = event->value; + break; + case WSCONS_EVENT_MOUSE_DELTA_Y: + dy = -event->value; + break; +#ifdef WSCONS_EVENT_MOUSE_DELTA_Z + case WSCONS_EVENT_MOUSE_DELTA_Z: + dz = event->value; + break; +#endif + default: + xf86Msg(X_WARNING, "%s: bad wsmouse event type=%d\n", pInfo->name, + event->type); + continue; + } + + pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw); + ++event; + } + return; +} + + +/* This function is called when the protocol is "wsmouse". */ +static Bool +wsconsPreInit(InputInfoPtr pInfo, const char *protocol, int flags) +{ + MouseDevPtr pMse = pInfo->private; + + pMse->protocol = protocol; + xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol); + + /* Collect the options, and process the common options. */ + xf86CollectInputOptions(pInfo, NULL, NULL); + xf86ProcessCommonOptions(pInfo, pInfo->options); + + /* Check if the device can be opened. */ + pInfo->fd = xf86OpenSerial(pInfo->options); + if (pInfo->fd == -1) { + if (xf86GetAllowMouseOpenFail()) + xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name); + else { + xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name); + xfree(pMse); + return FALSE; + } + } + xf86CloseSerial(pInfo->fd); + pInfo->fd = -1; + + /* Process common mouse options (like Emulate3Buttons, etc). */ + pMse->CommonOptions(pInfo); + + /* Setup the local input proc. */ + pInfo->read_input = wsconsReadInput; + + pInfo->flags |= XI86_CONFIGURED; + return TRUE; +} +#endif + +#if defined(USBMOUSE_SUPPORT) + +typedef struct _UsbMseRec { + int packetSize; + int iid; + hid_item_t loc_x; /* x locator item */ + hid_item_t loc_y; /* y locator item */ + hid_item_t loc_z; /* z (wheel) locator item */ + hid_item_t loc_btn[MSE_MAXBUTTONS]; /* buttons locator items */ + unsigned char *buffer; +} UsbMseRec, *UsbMsePtr; + +static int +usbMouseProc(DeviceIntPtr pPointer, int what) +{ + InputInfoPtr pInfo; + MouseDevPtr pMse; + UsbMsePtr pUsbMse; + unsigned char map[MSE_MAXBUTTONS + 1]; + int nbuttons; + + pInfo = pPointer->public.devicePrivate; + pMse = pInfo->private; + pMse->device = pPointer; + pUsbMse = pMse->mousePriv; + + switch (what) { + case DEVICE_INIT: + pPointer->public.on = FALSE; + + for (nbuttons = 0; nbuttons < MSE_MAXBUTTONS; ++nbuttons) + map[nbuttons + 1] = nbuttons + 1; + + InitPointerDeviceStruct((DevicePtr)pPointer, + map, + min(pMse->buttons, MSE_MAXBUTTONS), + miPointerGetMotionEvents, + pMse->Ctrl, + miPointerGetMotionBufferSize()); + + /* X valuator */ + xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1); + xf86InitValuatorDefaults(pPointer, 0); + /* Y valuator */ + xf86InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1); + xf86InitValuatorDefaults(pPointer, 1); + xf86MotionHistoryAllocate(pInfo); + break; + + case DEVICE_ON: + pInfo->fd = xf86OpenSerial(pInfo->options); + if (pInfo->fd == -1) + xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name); + else { + pMse->buffer = XisbNew(pInfo->fd, pUsbMse->packetSize); + if (!pMse->buffer) { + xfree(pMse); + xf86CloseSerial(pInfo->fd); + pInfo->fd = -1; + } else { + xf86FlushInput(pInfo->fd); + if (!xf86InstallSIGIOHandler (pInfo->fd, usbSigioReadInput, + pInfo)) + AddEnabledDevice(pInfo->fd); + } + } + pMse->lastButtons = 0; + pMse->emulateState = 0; + pPointer->public.on = TRUE; + break; + + case DEVICE_OFF: + case DEVICE_CLOSE: + if (pInfo->fd != -1) { + RemoveEnabledDevice(pInfo->fd); + if (pUsbMse->packetSize > 8 && pUsbMse->buffer) { + xfree(pUsbMse->buffer); + } + if (pMse->buffer) { + XisbFree(pMse->buffer); + pMse->buffer = NULL; + } + xf86CloseSerial(pInfo->fd); + pInfo->fd = -1; + } + pPointer->public.on = FALSE; + usleep(300000); + break; + } + return Success; +} + +static void +usbReadInput(InputInfoPtr pInfo) +{ + MouseDevPtr pMse; + UsbMsePtr pUsbMse; + int buttons = pMse->lastButtons; + int dx = 0, dy = 0, dz = 0, dw = 0; + int n, c; + unsigned char *pBuf; + + pMse = pInfo->private; + pUsbMse = pMse->mousePriv; + + XisbBlockDuration(pMse->buffer, -1); + pBuf = pUsbMse->buffer; + n = 0; + while ((c = XisbRead(pMse->buffer)) >= 0 && n < pUsbMse->packetSize) { + pBuf[n++] = (unsigned char)c; + } + if (n == 0) + return; + if (n != pUsbMse->packetSize) { + xf86Msg(X_WARNING, "%s: incomplete packet, size %d\n", pInfo->name, + n); + } + /* discard packets with an id that don't match the mouse */ + /* XXX this is probably not the right thing */ + if (pUsbMse->iid != 0) { + if (*pBuf++ != pUsbMse->iid) + return; + } + dx = hid_get_data(pBuf, &pUsbMse->loc_x); + dy = hid_get_data(pBuf, &pUsbMse->loc_y); + dz = hid_get_data(pBuf, &pUsbMse->loc_z); + + buttons = 0; + for (n = 0; n < pMse->buttons; n++) { + if (hid_get_data(pBuf, &pUsbMse->loc_btn[n])) + buttons |= (1 << UMS_BUT(n)); + } + pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw); + return; +} + +static void +usbSigioReadInput (int fd, void *closure) +{ + usbReadInput ((InputInfoPtr) closure); +} + +/* This function is called when the protocol is "usb". */ +static Bool +usbPreInit(InputInfoPtr pInfo, const char *protocol, int flags) +{ + MouseDevPtr pMse = pInfo->private; + UsbMsePtr pUsbMse; + report_desc_t reportDesc; + int i; + + pUsbMse = xalloc(sizeof(UsbMseRec)); + if (pUsbMse == NULL) { + xf86Msg(X_ERROR, "%s: cannot allocate UsbMouseRec\n", pInfo->name); + xfree(pMse); + return FALSE; + } + + pMse->protocol = protocol; + xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol); + + /* Collect the options, and process the common options. */ + xf86CollectInputOptions(pInfo, NULL, NULL); + xf86ProcessCommonOptions(pInfo, pInfo->options); + + /* Check if the device can be opened. */ + pInfo->fd = xf86OpenSerial(pInfo->options); + if (pInfo->fd == -1) { + if (xf86GetAllowMouseOpenFail()) + xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name); + else { + xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name); + xfree(pUsbMse); + xfree(pMse); + return FALSE; + } + } + /* Get USB informations */ + reportDesc = hid_get_report_desc(pInfo->fd); + /* Get packet size & iid */ +#ifdef USB_NEW_HID + if (ioctl(pInfo->fd, USB_GET_REPORT_ID, &pUsbMse->iid) == -1) { + xf86Msg(X_ERROR, "Error ioctl USB_GET_REPORT_ID on %s : %s\n", + pInfo->name, strerror(errno)); + return FALSE; + } + pUsbMse->packetSize = hid_report_size(reportDesc, hid_input, + pUsbMse->iid); +#else + pUsbMse->packetSize = hid_report_size(reportDesc, hid_input, + &pUsbMse->iid); +#endif + /* Allocate buffer */ + if (pUsbMse->packetSize <= 8) { + pUsbMse->buffer = pMse->protoBuf; + } else { + pUsbMse->buffer = xalloc(pUsbMse->packetSize); + } + if (pUsbMse->buffer == NULL) { + xf86Msg(X_ERROR, "%s: cannot allocate buffer\n", pInfo->name); + xfree(pUsbMse); + xfree(pMse); + xf86CloseSerial(pInfo->fd); + return FALSE; + } +#ifdef USB_NEW_HID + if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X), + hid_input, &pUsbMse->loc_x, pUsbMse->iid) < 0) { + xf86Msg(X_WARNING, "%s: no x locator\n"); + } + if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y), + hid_input, &pUsbMse->loc_y, pUsbMse->iid) < 0) { + xf86Msg(X_WARNING, "%s: no y locator\n"); + } + if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL), + hid_input, &pUsbMse->loc_z, pUsbMse->iid) < 0) { + } +#else + if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_X), + hid_input, &pUsbMse->loc_x) < 0) { + xf86Msg(X_WARNING, "%s: no x locator\n"); + } + if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_Y), + hid_input, &pUsbMse->loc_y) < 0) { + xf86Msg(X_WARNING, "%s: no y locator\n"); + } + if (hid_locate(reportDesc, HID_USAGE2(HUP_GENERIC_DESKTOP, HUG_WHEEL), + hid_input, &pUsbMse->loc_z) < 0) { + } +#endif + /* Probe for number of buttons */ + for (i = 1; i <= MSE_MAXBUTTONS; i++) { + if (!hid_locate(reportDesc, HID_USAGE2(HUP_BUTTON, i), + hid_input, &pUsbMse->loc_btn[i-1] +#ifdef USB_NEW_HID + , pUsbMse->iid +#endif + )) + break; + } + pMse->buttons = i-1; + + xf86CloseSerial(pInfo->fd); + pInfo->fd = -1; + + /* Private structure */ + pMse->mousePriv = pUsbMse; + + /* Process common mouse options (like Emulate3Buttons, etc). */ + pMse->CommonOptions(pInfo); + + /* Setup the local procs. */ + pInfo->device_control = usbMouseProc; + pInfo->read_input = usbReadInput; + + pInfo->flags |= XI86_CONFIGURED; + return TRUE; +} +#endif /* USBMOUSE */ + +static Bool +bsdMousePreInit(InputInfoPtr pInfo, const char *protocol, int flags) +{ + /* The protocol is guaranteed to be one of the internalNames[] */ +#ifdef WSCONS_SUPPORT + if (xf86NameCmp(protocol, "WSMouse") == 0) { + return wsconsPreInit(pInfo, protocol, flags); + } +#endif +#ifdef USBMOUSE_SUPPORT + if (xf86NameCmp(protocol, "usb") == 0) { + return usbPreInit(pInfo, protocol, flags); + } +#endif + return TRUE; +} + +OSMouseInfoPtr +xf86OSMouseInit(int flags) +{ + OSMouseInfoPtr p; + + p = xcalloc(sizeof(OSMouseInfoRec), 1); + if (!p) + return NULL; + p->SupportedInterfaces = SupportedInterfaces; + p->BuiltinNames = BuiltinNames; + p->DefaultProtocol = DefaultProtocol; + p->CheckProtocol = CheckProtocol; +#if defined(__FreeBSD__) && defined(MOUSE_PROTO_SYSMOUSE) + p->SetupAuto = SetupAuto; + p->SetPS2Res = SetSysMouseRes; + p->SetBMRes = SetSysMouseRes; + p->SetMiscRes = SetSysMouseRes; +#endif + p->PreInit = bsdMousePreInit; + return p; +} diff --git a/hw/xfree86/os-support/bsd/i386_video.c b/hw/xfree86/os-support/bsd/i386_video.c new file mode 100644 index 000000000..3c056ce55 --- /dev/null +++ b/hw/xfree86/os-support/bsd/i386_video.c @@ -0,0 +1,877 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/i386_video.c,v 1.2 2002/09/10 15:53:31 dawes Exp $ */ +/* + * Copyright 1992 by Rich Murphey <Rich@Rice.edu> + * 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 Rich Murphey and David Wexelblat + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. Rich Murphey and + * David Wexelblat make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RICH MURPHEY 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. + * + */ + +/* $XConsortium: bsd_video.c /main/10 1996/10/25 11:37:57 kaleb $ */ + +#include "X.h" +#include "xf86.h" +#include "xf86Priv.h" + +#ifdef HAS_MTRR_SUPPORT +#ifndef __NetBSD__ +#include <sys/types.h> +#include <sys/memrange.h> +#else +#include "memrange.h" +#endif +#define X_MTRR_ID "XFree86" +#endif + +#if defined(HAS_MTRR_BUILTIN) && defined(__NetBSD__) +#include <machine/mtrr.h> +#include <machine/sysarch.h> +#include <sys/queue.h> +#endif + +#include "xf86_OSlib.h" +#include "xf86OSpriv.h" + +#if defined(__NetBSD__) && !defined(MAP_FILE) +#define MAP_FLAGS MAP_SHARED +#else +#define MAP_FLAGS (MAP_FILE | MAP_SHARED) +#endif + +#ifndef MAP_FAILED +#define MAP_FAILED ((caddr_t)-1) +#endif + +#ifdef __OpenBSD__ +#define SYSCTL_MSG "\tCheck that you have set 'machdep.allowaperture=1'\n"\ + "\tin /etc/sysctl.conf and reboot your machine\n" \ + "\trefer to xf86(4) for details\n" +#define SYSCTL_MSG2 \ + "Check that you have set 'machdep.allowaperture=2'\n" \ + "\tin /etc/sysctl.conf and reboot your machine\n" \ + "\trefer to xf86(4) for details\n" +#endif + +/***************************************************************************/ +/* Video Memory Mapping section */ +/***************************************************************************/ + +static Bool useDevMem = FALSE; +static int devMemFd = -1; + +#ifdef HAS_APERTURE_DRV +#define DEV_APERTURE "/dev/xf86" +#endif +#define DEV_MEM "/dev/mem" + +static pointer mapVidMem(int, unsigned long, unsigned long, int); +static void unmapVidMem(int, pointer, unsigned long); + +#ifdef HAS_MTRR_SUPPORT +static pointer setWC(int, unsigned long, unsigned long, Bool, MessageType); +static void undoWC(int, pointer); +static Bool cleanMTRR(void); +#endif +#if defined(HAS_MTRR_BUILTIN) && defined(__NetBSD__) +static pointer NetBSDsetWC(int, unsigned long, unsigned long, Bool, + MessageType); +static void NetBSDundoWC(int, pointer); +#endif + + +/* + * Check if /dev/mem can be mmap'd. If it can't print a warning when + * "warn" is TRUE. + */ +static void +checkDevMem(Bool warn) +{ + static Bool devMemChecked = FALSE; + int fd; + pointer base; + + if (devMemChecked) + return; + devMemChecked = TRUE; + + if ((fd = open(DEV_MEM, O_RDWR)) >= 0) + { + /* Try to map a page at the VGA address */ + base = mmap((caddr_t)0, 4096, PROT_READ|PROT_WRITE, + MAP_FLAGS, fd, (off_t)0xA0000); + + if (base != MAP_FAILED) + { + munmap((caddr_t)base, 4096); + devMemFd = fd; + useDevMem = TRUE; + return; + } else { + /* This should not happen */ + if (warn) + { + xf86Msg(X_WARNING, "checkDevMem: failed to mmap %s (%s)\n", + DEV_MEM, strerror(errno)); + } + useDevMem = FALSE; + return; + } + } +#ifndef HAS_APERTURE_DRV + if (warn) + { + xf86Msg(X_WARNING, "checkDevMem: failed to open %s (%s)\n", + DEV_MEM, strerror(errno)); + } + useDevMem = FALSE; + return; +#else + /* Failed to open /dev/mem, try the aperture driver */ + if ((fd = open(DEV_APERTURE, O_RDWR)) >= 0) + { + /* Try to map a page at the VGA address */ + base = mmap((caddr_t)0, 4096, PROT_READ|PROT_WRITE, + MAP_FLAGS, fd, (off_t)0xA0000); + + if (base != MAP_FAILED) + { + munmap((caddr_t)base, 4096); + devMemFd = fd; + useDevMem = TRUE; + xf86Msg(X_INFO, "checkDevMem: using aperture driver %s\n", + DEV_APERTURE); + return; + } else { + + if (warn) + { + xf86Msg(X_WARNING, "checkDevMem: failed to mmap %s (%s)\n", + DEV_APERTURE, strerror(errno)); + } + } + } else { + if (warn) + { +#ifndef __OpenBSD__ + xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n" + "\t(%s)\n", DEV_MEM, DEV_APERTURE, strerror(errno)); +#else /* __OpenBSD__ */ + xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n" + "\t(%s)\n%s", DEV_MEM, DEV_APERTURE, strerror(errno), + SYSCTL_MSG); +#endif /* __OpenBSD__ */ + } + } + + useDevMem = FALSE; + return; + +#endif +} + +void +xf86OSInitVidMem(VidMemInfoPtr pVidMem) +{ + checkDevMem(TRUE); + pVidMem->linearSupported = useDevMem; + pVidMem->mapMem = mapVidMem; + pVidMem->unmapMem = unmapVidMem; + +#ifdef HAS_MTRR_SUPPORT + if (useDevMem) { + if (cleanMTRR()) { + pVidMem->setWC = setWC; + pVidMem->undoWC = undoWC; + } + } +#endif +#if defined(HAS_MTRR_BUILTIN) && defined(__NetBSD__) + pVidMem->setWC = NetBSDsetWC; + pVidMem->undoWC = NetBSDundoWC; +#endif + pVidMem->initialised = TRUE; +} + +static pointer +mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags) +{ + pointer base; + + checkDevMem(FALSE); + + if (useDevMem) + { + if (devMemFd < 0) + { + FatalError("xf86MapVidMem: failed to open %s (%s)\n", + DEV_MEM, strerror(errno)); + } + base = mmap((caddr_t)0, Size, PROT_READ|PROT_WRITE, + MAP_FLAGS, devMemFd, (off_t)Base); + if (base == MAP_FAILED) + { + FatalError("%s: could not mmap %s [s=%x,a=%x] (%s)\n", + "xf86MapVidMem", DEV_MEM, Size, Base, + strerror(errno)); + } + return(base); + } + + /* else, mmap /dev/vga */ + if ((unsigned long)Base < 0xA0000 || (unsigned long)Base >= 0xC0000) + { + FatalError("%s: Address 0x%x outside allowable range\n", + "xf86MapVidMem", Base); + } + base = mmap(0, Size, PROT_READ|PROT_WRITE, MAP_FLAGS, + xf86Info.screenFd, + (unsigned long)Base - 0xA0000 + ); + if (base == MAP_FAILED) + { + FatalError("xf86MapVidMem: Could not mmap /dev/vga (%s)\n", + strerror(errno)); + } + return(base); +} + +static void +unmapVidMem(int ScreenNum, pointer Base, unsigned long Size) +{ + munmap((caddr_t)Base, Size); +} + +/* + * Read BIOS via mmap()ing DEV_MEM + */ + +int +xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf, + int Len) +{ + unsigned char *ptr; + int psize; + int mlen; + + checkDevMem(TRUE); + if (devMemFd == -1) { + return(-1); + } + + psize = xf86getpagesize(); + Offset += Base & (psize - 1); + Base &= ~(psize - 1); + mlen = (Offset + Len + psize - 1) & ~(psize - 1); + ptr = (unsigned char *)mmap((caddr_t)0, mlen, PROT_READ, + MAP_SHARED, devMemFd, (off_t)Base); + if ((long)ptr == -1) + { + xf86Msg(X_WARNING, + "xf86ReadBIOS: %s mmap[s=%x,a=%x,o=%x] failed (%s)\n", + DEV_MEM, Len, Base, Offset, strerror(errno)); +#ifdef __OpenBSD__ + if (Base < 0xa0000) { + xf86Msg(X_WARNING, SYSCTL_MSG2); + } +#endif + return(-1); + } +#ifdef DEBUG + ErrorF("xf86ReadBIOS: BIOS at 0x%08x has signature 0x%04x\n", + Base, ptr[0] | (ptr[1] << 8)); +#endif + (void)memcpy(Buf, (void *)(ptr + Offset), Len); + (void)munmap((caddr_t)ptr, mlen); +#ifdef DEBUG + xf86MsgVerb(X_INFO, 3, "xf86ReadBIOS(%x, %x, Buf, %x)" + "-> %02x %02x %02x %02x...\n", + Base, Offset, Len, Buf[0], Buf[1], Buf[2], Buf[3]); +#endif + return(Len); +} + + +#ifdef USE_I386_IOPL +/***************************************************************************/ +/* I/O Permissions section */ +/***************************************************************************/ + +static Bool ExtendedEnabled = FALSE; + +void +xf86EnableIO() +{ + if (ExtendedEnabled) + return; + + if (i386_iopl(TRUE) < 0) + { +#ifndef __OpenBSD__ + FatalError("%s: Failed to set IOPL for extended I/O\n", + "xf86EnableIO"); +#else + FatalError("%s: Failed to set IOPL for extended I/O\n%s", + "xf86EnableIO", SYSCTL_MSG); +#endif + } + ExtendedEnabled = TRUE; + + return; +} + +void +xf86DisableIO() +{ + if (!ExtendedEnabled) + return; + + i386_iopl(FALSE); + ExtendedEnabled = FALSE; + + return; +} + +#endif /* USE_I386_IOPL */ + +#ifdef USE_DEV_IO +static int IoFd = -1; + +void +xf86EnableIO() +{ + if (IoFd >= 0) + return; + + if ((IoFd = open("/dev/io", O_RDWR)) == -1) + { + FatalError("xf86EnableIO: " + "Failed to open /dev/io for extended I/O\n"); + } + return; +} + +void +xf86DisableIO() +{ + if (IoFd < 0) + return; + + close(IoFd); + IoFd = -1; + return; +} + +#endif + + +/***************************************************************************/ +/* Interrupt Handling section */ +/***************************************************************************/ + +Bool +xf86DisableInterrupts() +{ + +#ifdef __GNUC__ + __asm__ __volatile__("cli"); +#else + asm("cli"); +#endif /* __GNUC__ */ + + return(TRUE); +} + +void +xf86EnableInterrupts() +{ + +#ifdef __GNUC__ + __asm__ __volatile__("sti"); +#else + asm("sti"); +#endif /* __GNUC__ */ + + return; +} + + +#ifdef __NetBSD__ +/***************************************************************************/ +/* Set TV output mode */ +/***************************************************************************/ +void +xf86SetTVOut(int mode) +{ + switch (xf86Info.consType) + { +#ifdef PCCONS_SUPPORT + case PCCONS:{ + + if (ioctl (xf86Info.consoleFd, CONSOLE_X_TV_ON, &mode) < 0) + { + xf86Msg(X_WARNING, + "xf86SetTVOut: Could not set console to TV output, %s\n", + strerror(errno)); + } + } + break; +#endif /* PCCONS_SUPPORT */ + + default: + FatalError("Xf86SetTVOut: Unsupported console\n"); + break; + } + return; +} + +void +xf86SetRGBOut() +{ + switch (xf86Info.consType) + { +#ifdef PCCONS_SUPPORT + case PCCONS:{ + + if (ioctl (xf86Info.consoleFd, CONSOLE_X_TV_OFF, 0) < 0) + { + xf86Msg(X_WARNING, + "xf86SetTVOut: Could not set console to RGB output, %s\n", + strerror(errno)); + } + } + break; +#endif /* PCCONS_SUPPORT */ + + default: + FatalError("Xf86SetTVOut: Unsupported console\n"); + break; + } + return; +} +#endif + + +#ifdef HAS_MTRR_SUPPORT +/* memory range (MTRR) support for FreeBSD */ + +/* + * This code is experimental. Some parts may be overkill, and other parts + * may be incomplete. + */ + +/* + * getAllRanges returns the full list of memory ranges with attributes set. + */ + +static struct mem_range_desc * +getAllRanges(int *nmr) +{ + struct mem_range_desc *mrd; + struct mem_range_op mro; + + /* + * Find how many ranges there are. If this fails, then the kernel + * probably doesn't have MTRR support. + */ + mro.mo_arg[0] = 0; + if (ioctl(devMemFd, MEMRANGE_GET, &mro)) + return NULL; + *nmr = mro.mo_arg[0]; + mrd = xnfalloc(*nmr * sizeof(struct mem_range_desc)); + mro.mo_arg[0] = *nmr; + mro.mo_desc = mrd; + if (ioctl(devMemFd, MEMRANGE_GET, &mro)) { + xfree(mrd); + return NULL; + } + return mrd; +} + +/* + * cleanMTRR removes any memory attribute that may be left by a previous + * X server. Normally there won't be any, but this takes care of the + * case where a server crashed without being able finish cleaning up. + */ + +static Bool +cleanMTRR() +{ + struct mem_range_desc *mrd; + struct mem_range_op mro; + int nmr, i; + + /* This shouldn't happen */ + if (devMemFd < 0) + return FALSE; + + if (!(mrd = getAllRanges(&nmr))) + return FALSE; + + for (i = 0; i < nmr; i++) { + if (strcmp(mrd[i].mr_owner, X_MTRR_ID) == 0 && + (mrd[i].mr_flags & MDF_ACTIVE)) { +#ifdef DEBUG + ErrorF("Clean for (0x%lx,0x%lx)\n", + (unsigned long)mrd[i].mr_base, + (unsigned long)rd[i].mr_len); +#endif + if (mrd[i].mr_flags & MDF_FIXACTIVE) { + mro.mo_arg[0] = MEMRANGE_SET_UPDATE; + mrd[i].mr_flags = MDF_UNCACHEABLE; + } else { + mro.mo_arg[0] = MEMRANGE_SET_REMOVE; + } + mro.mo_desc = mrd + i; + ioctl(devMemFd, MEMRANGE_SET, &mro); + } + } +#ifdef DEBUG + sleep(10); +#endif + xfree(mrd); + return TRUE; +} + +typedef struct x_RangeRec { + struct mem_range_desc mrd; + Bool wasWC; + struct x_RangeRec * next; +} RangeRec, *RangePtr; + +static void +freeRangeList(RangePtr range) +{ + RangePtr rp; + + while (range) { + rp = range; + range = rp->next; + xfree(rp); + } +} + +static RangePtr +dupRangeList(RangePtr list) +{ + RangePtr new = NULL, rp, p; + + rp = list; + while (rp) { + p = xnfalloc(sizeof(RangeRec)); + *p = *rp; + p->next = new; + new = p; + rp = rp->next; + } + return new; +} + +static RangePtr +sortRangeList(RangePtr list) +{ + RangePtr rp1, rp2, copy, sorted = NULL, minp, prev, minprev; + unsigned long minBase; + + /* Sort by base address */ + rp1 = copy = dupRangeList(list); + while (rp1) { + minBase = rp1->mrd.mr_base; + minp = rp1; + minprev = NULL; + prev = rp1; + rp2 = rp1->next; + while (rp2) { + if (rp2->mrd.mr_base < minBase) { + minBase = rp2->mrd.mr_base; + minp = rp2; + minprev = prev; + } + prev = rp2; + rp2 = rp2->next; + } + if (minprev) { + minprev->next = minp->next; + rp1 = copy; + } else { + rp1 = minp->next; + } + minp->next = sorted; + sorted = minp; + } + return sorted; +} + +/* + * findRanges returns a list of ranges that overlap the specified range. + */ + +static void +findRanges(unsigned long base, unsigned long size, RangePtr *ucp, RangePtr *wcp) +{ + struct mem_range_desc *mrd; + int nmr, i; + RangePtr rp, *p; + + if (!(mrd = getAllRanges(&nmr))) + return; + + for (i = 0; i < nmr; i++) { + if ((mrd[i].mr_flags & MDF_ACTIVE) && + mrd[i].mr_base < base + size && + mrd[i].mr_base + mrd[i].mr_len > base) { + if (mrd[i].mr_flags & MDF_WRITECOMBINE) + p = wcp; + else if (mrd[i].mr_flags & MDF_UNCACHEABLE) + p = ucp; + else + continue; + rp = xnfalloc(sizeof(RangeRec)); + rp->mrd = mrd[i]; + rp->next = *p; + *p = rp; + } + } + xfree(mrd); +} + +/* + * This checks if the existing overlapping ranges fully cover the requested + * range. Is this overkill? + */ + +static Bool +fullCoverage(unsigned long base, unsigned long size, RangePtr overlap) +{ + RangePtr rp1, sorted = NULL; + unsigned long end; + + sorted = sortRangeList(overlap); + /* Look for gaps */ + rp1 = sorted; + end = base + size; + while (rp1) { + if (rp1->mrd.mr_base > base) { + freeRangeList(sorted); + return FALSE; + } else { + base = rp1->mrd.mr_base + rp1->mrd.mr_len; + } + if (base >= end) { + freeRangeList(sorted); + return TRUE; + } + rp1 = rp1->next; + } + freeRangeList(sorted); + return FALSE; +} + +static pointer +addWC(int screenNum, unsigned long base, unsigned long size, MessageType from) +{ + RangePtr uc = NULL, wc = NULL, retlist = NULL; + struct mem_range_desc mrd; + struct mem_range_op mro; + + findRanges(base, size, &uc, &wc); + + /* See of the full range is already WC */ + if (!uc && fullCoverage(base, size, wc)) { + xf86DrvMsg(screenNum, from, + "Write-combining range (0x%lx,0x%lx) was already set\n", + base, size); + return NULL; + } + + /* Otherwise, try to add the new range */ + mrd.mr_base = base; + mrd.mr_len = size; + strcpy(mrd.mr_owner, X_MTRR_ID); + mrd.mr_flags = MDF_WRITECOMBINE; + mro.mo_desc = &mrd; + mro.mo_arg[0] = MEMRANGE_SET_UPDATE; + if (ioctl(devMemFd, MEMRANGE_SET, &mro)) { + xf86DrvMsg(screenNum, X_WARNING, + "Failed to set write-combining range " + "(0x%lx,0x%lx)\n", base, size); + return NULL; + } else { + xf86DrvMsg(screenNum, from, + "Write-combining range (0x%lx,0x%lx)\n", base, size); + retlist = xnfalloc(sizeof(RangeRec)); + retlist->mrd = mrd; + retlist->wasWC = FALSE; + retlist->next = NULL; + return retlist; + } +} + +static pointer +delWC(int screenNum, unsigned long base, unsigned long size, MessageType from) +{ + RangePtr uc = NULL, wc = NULL, retlist = NULL; + struct mem_range_desc mrd; + struct mem_range_op mro; + + findRanges(base, size, &uc, &wc); + + /* + * See of the full range is already not WC, or if there is full + * coverage from UC ranges. + */ + if (!wc || fullCoverage(base, size, uc)) { + xf86DrvMsg(screenNum, from, + "Write-combining range (0x%lx,0x%lx) was already clear\n", + base, size); + return NULL; + } + + /* Otherwise, try to add the new range */ + mrd.mr_base = base; + mrd.mr_len = size; + strcpy(mrd.mr_owner, X_MTRR_ID); + mrd.mr_flags = MDF_UNCACHEABLE; + mro.mo_desc = &mrd; + mro.mo_arg[0] = MEMRANGE_SET_UPDATE; + if (ioctl(devMemFd, MEMRANGE_SET, &mro)) { + xf86DrvMsg(screenNum, X_WARNING, + "Failed to remove write-combining range " + "(0x%lx,0x%lx)\n", base, size); + /* XXX Should then remove all of the overlapping WC ranges */ + return NULL; + } else { + xf86DrvMsg(screenNum, from, + "Removed Write-combining range (0x%lx,0x%lx)\n", + base, size); + retlist = xnfalloc(sizeof(RangeRec)); + retlist->mrd = mrd; + retlist->wasWC = TRUE; + retlist->next = NULL; + return retlist; + } +} + +static pointer +setWC(int screenNum, unsigned long base, unsigned long size, Bool enable, + MessageType from) +{ + if (enable) + return addWC(screenNum, base, size, from); + else + return delWC(screenNum, base, size, from); +} + +static void +undoWC(int screenNum, pointer list) +{ + RangePtr rp; + struct mem_range_op mro; + Bool failed; + + rp = list; + while (rp) { +#ifdef DEBUG + ErrorF("Undo for (0x%lx,0x%lx), %d\n", + (unsigned long)rp->mrd.mr_base, + (unsigned long)rp->mrd.mr_len, rp->wasWC); +#endif + failed = FALSE; + if (rp->wasWC) { + mro.mo_arg[0] = MEMRANGE_SET_UPDATE; + rp->mrd.mr_flags = MDF_WRITECOMBINE; + strcpy(rp->mrd.mr_owner, "unknown"); + } else { + mro.mo_arg[0] = MEMRANGE_SET_REMOVE; + } + mro.mo_desc = &rp->mrd; + + if (ioctl(devMemFd, MEMRANGE_SET, &mro)) { + if (!rp->wasWC) { + mro.mo_arg[0] = MEMRANGE_SET_UPDATE; + rp->mrd.mr_flags = MDF_UNCACHEABLE; + strcpy(rp->mrd.mr_owner, "unknown"); + if (ioctl(devMemFd, MEMRANGE_SET, &mro)) + failed = TRUE; + } else + failed = TRUE; + } + if (failed) { + xf86DrvMsg(screenNum, X_WARNING, + "Failed to restore MTRR range (0x%lx,0x%lx)\n", + (unsigned long)rp->mrd.mr_base, + (unsigned long)rp->mrd.mr_len); + } + rp = rp->next; + } +} + +#endif /* HAS_MTRR_SUPPORT */ + + +#if defined(HAS_MTRR_BUILTIN) && defined(__NetBSD__) +static pointer +NetBSDsetWC(int screenNum, unsigned long base, unsigned long size, Bool enable, + MessageType from) +{ + struct mtrr *mtrrp; + int n; + + xf86DrvMsg(screenNum, X_WARNING, + "%s MTRR %lx - %lx\n", enable ? "set" : "remove", + base, (base + size)); + + mtrrp = xnfalloc(sizeof (struct mtrr)); + mtrrp->base = base; + mtrrp->len = size; + mtrrp->type = MTRR_TYPE_WC; + + /* + * MTRR_PRIVATE will make this MTRR get reset automatically + * if this process exits, so we have no need for an explicit + * cleanup operation when starting a new server. + */ + + if (enable) + mtrrp->flags = MTRR_VALID | MTRR_PRIVATE; + else + mtrrp->flags = 0; + n = 1; + + if (i386_set_mtrr(mtrrp, &n) < 0) { + xfree(mtrrp); + return NULL; + } + return mtrrp; +} + +static void +NetBSDundoWC(int screenNum, pointer list) +{ + struct mtrr *mtrrp = (struct mtrr *)list; + int n; + + if (mtrrp == NULL) + return; + n = 1; + mtrrp->flags &= ~MTRR_VALID; + i386_set_mtrr(mtrrp, &n); + xfree(mtrrp); +} +#endif diff --git a/hw/xfree86/os-support/bsd/libusb/data.c b/hw/xfree86/os-support/bsd/libusb/data.c new file mode 100644 index 000000000..bb84e5566 --- /dev/null +++ b/hw/xfree86/os-support/bsd/libusb/data.c @@ -0,0 +1,91 @@ +/* $NetBSD: data.c,v 1.6 1999/09/20 04:48:12 lukem Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/libusb/data.c,v 1.1 2000/02/11 18:06:49 dawes Exp $ */ + +#include <assert.h> +#include <stdlib.h> +#include "usb.h" + +int +hid_get_data(void *p, hid_item_t *h) +{ + unsigned char *buf; + unsigned int hpos; + unsigned int hsize; + int data; + int i, end, offs; + + _DIAGASSERT(p != NULL); + _DIAGASSERT(h != NULL); + + buf = p; + hpos = h->pos; /* bit position of data */ + hsize = h->report_size; /* bit length of data */ + + if (hsize == 0) + return (0); + offs = hpos / 8; + end = (hpos + hsize) / 8 - offs; + data = 0; + for (i = 0; i <= end; i++) + data |= buf[offs + i] << (i*8); + data >>= hpos % 8; + data &= (1 << hsize) - 1; + if (h->logical_minimum < 0) { + /* Need to sign extend */ + hsize = sizeof data * 8 - hsize; + data = (data << hsize) >> hsize; + } + return (data); +} + +void +hid_set_data(void *p, hid_item_t *h, int data) +{ + unsigned char *buf; + unsigned int hpos; + unsigned int hsize; + int i, end, offs; + + _DIAGASSERT(p != NULL); + _DIAGASSERT(h != NULL); + + buf = p; + hpos = h->pos; /* bit position of data */ + hsize = h->report_size; /* bit length of data */ + + if (hsize != 32) + data &= (1 << hsize) - 1; + data <<= (hpos % 8); + + offs = hpos / 8; + end = (hpos + hsize) / 8 - offs; + data = 0; + for (i = 0; i <= end; i++) + buf[offs + i] |= (data >> (i*8)) & 0xff; +} diff --git a/hw/xfree86/os-support/bsd/libusb/descr.c b/hw/xfree86/os-support/bsd/libusb/descr.c new file mode 100644 index 000000000..f75418964 --- /dev/null +++ b/hw/xfree86/os-support/bsd/libusb/descr.c @@ -0,0 +1,72 @@ +/* $NetBSD: descr.c,v 1.7 1999/10/13 17:48:04 drochner Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/libusb/descr.c,v 1.1 2000/02/11 18:06:50 dawes Exp $ */ + +#include <sys/types.h> + +#include <assert.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <sys/time.h> + +#include <dev/usb/usb.h> + +#include "usb.h" +#include "usbvar.h" + +report_desc_t +hid_get_report_desc(fd) + int fd; +{ + struct usb_ctl_report_desc rep; + report_desc_t r; + + _DIAGASSERT(fd != -1); + + rep.size = 0; + if (ioctl(fd, USB_GET_REPORT_DESC, &rep) < 0) + return (0); + r = malloc(sizeof *r + rep.size); + if (r == 0) { + errno = ENOMEM; + return (0); + } + r->size = rep.size; + memcpy(r->data, rep.data, (unsigned int)rep.size); + return (r); +} + +void +hid_dispose_report_desc(r) + report_desc_t r; +{ + + free(r); +} diff --git a/hw/xfree86/os-support/bsd/libusb/parse.c b/hw/xfree86/os-support/bsd/libusb/parse.c new file mode 100644 index 000000000..8c1a8b8a2 --- /dev/null +++ b/hw/xfree86/os-support/bsd/libusb/parse.c @@ -0,0 +1,400 @@ +/* $NetBSD: parse.c,v 1.7 1999/10/13 17:48:04 drochner Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/libusb/parse.c,v 1.1 2000/02/11 18:06:50 dawes Exp $ */ + +#include <assert.h> +#include <stdlib.h> +#include <string.h> +#include <sys/time.h> + +#include <dev/usb/usb.h> +#include <dev/usb/usbhid.h> + +#include "usb.h" +#include "usbvar.h" + +#define MAXUSAGE 100 +struct hid_data { + u_char *start; + u_char *end; + u_char *p; + hid_item_t cur; + unsigned int usages[MAXUSAGE]; + int nusage; + int minset; + int multi; + int multimax; + int kindset; +}; + +static int min(int x, int y) { return x < y ? x : y; } + +static void +hid_clear_local(hid_item_t *c) +{ + + _DIAGASSERT(c != NULL); + + c->usage = 0; + c->usage_minimum = 0; + c->usage_maximum = 0; + c->designator_index = 0; + c->designator_minimum = 0; + c->designator_maximum = 0; + c->string_index = 0; + c->string_minimum = 0; + c->string_maximum = 0; + c->set_delimiter = 0; +} + +hid_data_t +hid_start_parse(report_desc_t d, int kindset) +{ + struct hid_data *s; + + _DIAGASSERT(d != NULL); + + s = malloc(sizeof *s); + memset(s, 0, sizeof *s); + s->start = s->p = d->data; + s->end = d->data + d->size; + s->kindset = kindset; + return (s); +} + +void +hid_end_parse(hid_data_t s) +{ + + _DIAGASSERT(s != NULL); + + while (s->cur.next) { + hid_item_t *hi = s->cur.next->next; + free(s->cur.next); + s->cur.next = hi; + } + free(s); +} + +int +hid_get_item(hid_data_t s, hid_item_t *h) +{ + hid_item_t *c; + unsigned int bTag = 0, bType = 0, bSize; + unsigned char *data; + int dval; + unsigned char *p; + hid_item_t *hi; + int i; + + _DIAGASSERT(s != NULL); + _DIAGASSERT(h != NULL); + + c = &s->cur; + + top: + if (s->multimax) { + if (s->multi < s->multimax) { + c->usage = s->usages[min(s->multi, s->nusage-1)]; + s->multi++; + *h = *c; + c->pos += c->report_size; + h->next = 0; + return (1); + } else { + c->report_count = s->multimax; + s->multimax = 0; + s->nusage = 0; + hid_clear_local(c); + } + } + for (;;) { + p = s->p; + if (p >= s->end) + return (0); + + bSize = *p++; + if (bSize == 0xfe) { + /* long item */ + bSize = *p++; + bSize |= *p++ << 8; + bTag = *p++; + data = p; + p += bSize; + } else { + /* short item */ + bTag = bSize >> 4; + bType = (bSize >> 2) & 3; + bSize &= 3; + if (bSize == 3) bSize = 4; + data = p; + p += bSize; + } + s->p = p; + /* + * The spec is unclear if the data is signed or unsigned. + */ + switch(bSize) { + case 0: + dval = 0; + break; + case 1: + dval = (int8_t)*data++; + break; + case 2: + dval = *data++; + dval |= *data++ << 8; + dval = (int16_t)dval; + break; + case 4: + dval = *data++; + dval |= *data++ << 8; + dval |= *data++ << 16; + dval |= *data++ << 24; + break; + default: + return (-1); + } + + switch (bType) { + case 0: /* Main */ + switch (bTag) { + case 8: /* Input */ + if (!(s->kindset & (1 << hid_input))) + continue; + c->kind = hid_input; + c->flags = dval; + ret: + if (c->flags & HIO_VARIABLE) { + s->multimax = c->report_count; + s->multi = 0; + c->report_count = 1; + if (s->minset) { + for (i = c->usage_minimum; + i <= c->usage_maximum; + i++) { + s->usages[s->nusage] = i; + if (s->nusage < MAXUSAGE-1) + s->nusage++; + } + s->minset = 0; + } + goto top; + } else { + if (s->minset) + c->usage = c->usage_minimum; + *h = *c; + h->next = 0; + c->pos += c->report_size * c->report_count; + hid_clear_local(c); + s->minset = 0; + return (1); + } + case 9: /* Output */ + if (!(s->kindset & (1 << hid_output))) + continue; + c->kind = hid_output; + c->flags = dval; + goto ret; + case 10: /* Collection */ + c->kind = hid_collection; + c->collection = dval; + c->collevel++; + *h = *c; + hid_clear_local(c); + s->nusage = 0; + return (1); + case 11: /* Feature */ + if (!(s->kindset & (1 << hid_feature))) + continue; + c->kind = hid_feature; + c->flags = dval; + goto ret; + case 12: /* End collection */ + c->kind = hid_endcollection; + c->collevel--; + *h = *c; + hid_clear_local(c); + s->nusage = 0; + return (1); + default: + return (-2); + } + + case 1: /* Global */ + switch (bTag) { + case 0: + c->_usage_page = dval << 16; + break; + case 1: + c->logical_minimum = dval; + break; + case 2: + c->logical_maximum = dval; + break; + case 3: + c->physical_maximum = dval; + break; + case 4: + c->physical_maximum = dval; + break; + case 5: + c->unit_exponent = dval; + break; + case 6: + c->unit = dval; + break; + case 7: + c->report_size = dval; + break; + case 8: + c->report_ID = dval; + break; + case 9: + c->report_count = dval; + break; + case 10: /* Push */ + hi = malloc(sizeof *hi); + *hi = s->cur; + c->next = hi; + break; + case 11: /* Pop */ + hi = c->next; + s->cur = *hi; + free(hi); + break; + default: + return (-3); + } + break; + case 2: /* Local */ + switch (bTag) { + case 0: + if (bSize == 1) + dval = c->_usage_page | (dval&0xff); + else if (bSize == 2) + dval = c->_usage_page | (dval&0xffff); + c->usage = dval; + if (s->nusage < MAXUSAGE) + s->usages[s->nusage++] = dval; + /* else XXX */ + break; + case 1: + s->minset = 1; + if (bSize == 1) + dval = c->_usage_page | (dval&0xff); + else if (bSize == 2) + dval = c->_usage_page | (dval&0xffff); + c->usage_minimum = dval; + break; + case 2: + if (bSize == 1) + dval = c->_usage_page | (dval&0xff); + else if (bSize == 2) + dval = c->_usage_page | (dval&0xffff); + c->usage_maximum = dval; + break; + case 3: + c->designator_index = dval; + break; + case 4: + c->designator_minimum = dval; + break; + case 5: + c->designator_maximum = dval; + break; + case 7: + c->string_index = dval; + break; + case 8: + c->string_minimum = dval; + break; + case 9: + c->string_maximum = dval; + break; + case 10: + c->set_delimiter = dval; + break; + default: + return (-4); + } + break; + default: + return (-5); + } + } +} + +int +hid_report_size(report_desc_t r, enum hid_kind k, int *idp) +{ + struct hid_data *d; + hid_item_t h; + int size, id; + + _DIAGASSERT(r != NULL); + /* idp may be NULL */ + + id = 0; + if (idp) + *idp = 0; + memset(&h, 0, sizeof h); + for (d = hid_start_parse(r, 1<<k); hid_get_item(d, &h); ) { + if (h.report_ID != 0) { + if (idp) + *idp = h.report_ID; + id = 8; + } + } + hid_end_parse(d); + size = h.pos + id; + return ((size + 7) / 8); +} + +int +hid_locate(desc, u, k, h) + report_desc_t desc; + unsigned int u; + enum hid_kind k; + hid_item_t *h; +{ + hid_data_t d; + + _DIAGASSERT(desc != NULL); + _DIAGASSERT(h != NULL); + + for (d = hid_start_parse(desc, 1<<k); hid_get_item(d, h); ) { + if (h->kind == k && !(h->flags & HIO_CONST) && h->usage == u) { + hid_end_parse(d); + return (1); + } + } + hid_end_parse(d); + h->report_size = 0; + return (0); +} diff --git a/hw/xfree86/os-support/bsd/libusb/usage.c b/hw/xfree86/os-support/bsd/libusb/usage.c new file mode 100644 index 000000000..9338e61d4 --- /dev/null +++ b/hw/xfree86/os-support/bsd/libusb/usage.c @@ -0,0 +1,195 @@ +/* $NetBSD: usage.c,v 1.4 1999/07/02 15:46:53 simonb Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/libusb/usage.c,v 1.1 2000/02/11 18:06:50 dawes Exp $ */ + +#include <ctype.h> +#include <err.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "usb.h" + +#define _PATH_HIDTABLE "/usr/share/misc/usb_hid_usages" + +struct usage_in_page { + char *name; + int usage; +}; + +static struct usage_page { + char *name; + int usage; + struct usage_in_page *page_contents; + int pagesize, pagesizemax; +} *pages; +static int npages, npagesmax; + +#ifdef DEBUG +void +dump_hid_table(void) +{ + int i, j; + + for (i = 0; i < npages; i++) { + printf("%d\t%s\n", pages[i].usage, pages[i].name); + for (j = 0; j < pages[i].pagesize; j++) { + printf("\t%d\t%s\n", pages[i].page_contents[j].usage, + pages[i].page_contents[j].name); + } + } +} +#endif + +void +hid_init(char *hidname) +{ + FILE *f; + char line[100], name[100], *p, *n; + int no; + int lineno; + struct usage_page *curpage = 0; + + if (hidname == 0) + hidname = _PATH_HIDTABLE; + + f = fopen(hidname, "r"); + if (f == NULL) + err(1, "%s", hidname); + for (lineno = 1; ; lineno++) { + if (fgets(line, sizeof line, f) == NULL) + break; + if (line[0] == '#') + continue; + for (p = line; *p && isspace(*p); p++) + ; + if (!*p) + continue; + if (sscanf(line, " * %[^\n]", name) == 1) + no = -1; + else if (sscanf(line, " 0x%x %[^\n]", &no, name) != 2 && + sscanf(line, " %d %[^\n]", &no, name) != 2) + errx(1, "file %s, line %d, syntax error\n", + hidname, lineno); + for (p = name; *p; p++) + if (isspace(*p) || *p == '.') + *p = '_'; + n = strdup(name); + if (!n) + err(1, "strdup"); + if (isspace(line[0])) { + if (!curpage) + errx(1, "file %s, line %d, syntax error\n", + hidname, lineno); + if (curpage->pagesize >= curpage->pagesizemax) { + curpage->pagesizemax += 10; + curpage->page_contents = + realloc(curpage->page_contents, + curpage->pagesizemax * + sizeof (struct usage_in_page)); + if (!curpage->page_contents) + err(1, "realloc"); + } + curpage->page_contents[curpage->pagesize].name = n; + curpage->page_contents[curpage->pagesize].usage = no; + curpage->pagesize++; + } else { + if (npages >= npagesmax) { + if (pages == 0) { + npagesmax = 5; + pages = malloc(npagesmax * + sizeof (struct usage_page)); + } else { + npagesmax += 5; + pages = realloc(pages, + npagesmax * + sizeof (struct usage_page)); + } + if (!pages) + err(1, "alloc"); + } + curpage = &pages[npages++]; + curpage->name = n; + curpage->usage = no; + curpage->pagesize = 0; + curpage->pagesizemax = 10; + curpage->page_contents = + malloc(curpage->pagesizemax * + sizeof (struct usage_in_page)); + if (!curpage->page_contents) + err(1, "malloc"); + } + } + fclose(f); +#ifdef DEBUG + dump_hid_table(); +#endif +} + +char * +hid_usage_page(int i) +{ + static char b[10]; + int k; + + if (!pages) + errx(1, "no hid table\n"); + + for (k = 0; k < npages; k++) + if (pages[k].usage == i) + return pages[k].name; + sprintf(b, "0x%02x", i); + return b; +} + +char * +hid_usage_in_page(unsigned int u) +{ + int page = HID_PAGE(u); + int i = HID_USAGE(u); + static char b[100]; + int j, k, us; + + for (k = 0; k < npages; k++) + if (pages[k].usage == page) + break; + if (k >= npages) + goto bad; + for (j = 0; j < pages[k].pagesize; j++) { + us = pages[k].page_contents[j].usage; + if (us == -1) { + sprintf(b, pages[k].page_contents[j].name, i); + return b; + } + if (us == i) + return pages[k].page_contents[j].name; + } + bad: + sprintf(b, "0x%02x", i); + return b; +} diff --git a/hw/xfree86/os-support/bsd/libusb/usb.3 b/hw/xfree86/os-support/bsd/libusb/usb.3 new file mode 100644 index 000000000..f88a28cd6 --- /dev/null +++ b/hw/xfree86/os-support/bsd/libusb/usb.3 @@ -0,0 +1,191 @@ +.\" $NetBSD: usb.3,v 1.9 1999/11/08 22:33:40 augustss Exp $ +.\" +.\" Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/libusb/usb.3,v 1.1 2000/02/11 18:06:50 dawes Exp $ +.\" +.Dd May 11, 1999 +.Dt USB 3 +.Os +.Sh NAME +.Nm usb , +.Nm hid_get_report_desc , +.Nm hid_dispose_report_desc , +.Nm hid_start_parse , +.Nm hid_end_parse , +.Nm hid_get_item , +.Nm hid_report_size , +.Nm hid_locate , +.Nm hid_usage_page , +.Nm hid_usage_in_page , +.Nm hid_init , +.Nm hid_get_data , +.Nm hid_set_data +.Nd USB HID access routines +.Sh LIBRARY +.Lb libusb +.Sh SYNOPSIS +.Fd #include <usb.h> +.Ft report_desc_t +.Fn hid_get_report_desc "int file" +.Ft void +.Fn hid_dispose_report_desc "report_desc_t d" +.Ft hid_data_t +.Fn hid_start_parse "report_desc_t d" "int kindset" +.Ft void +.Fn hid_end_parse "hid_data_t s" +.Ft int +.Fn hid_get_item "hid_data_t s" "hid_item_t *h" +.Ft int +.Fn hid_report_size "report_desc_t d" "hid_kind_t k" "int *idp" +.Ft int +.Fn hid_locate "report_desc_t d" "u_int usage" "hid_kind_t k" "hid_item_t *h" +.Ft char * +.Fn hid_usage_page "int i" +.Ft char * +.Fn hid_usage_in_page "u_int u" +.Ft void +.Fn hid_init "char *file" +.Ft int +.Fn hid_get_data "void *data" "hid_item_t *h" +.Ft void +.Fn hid_set_data "void *data" "hid_item_t *h" "u_int data" +.Sh DESCRIPTION +The +.Nm +library provides routines to extract data from USB Human Interface Devices. +.Ss INTRODUCTION +USB HID devices send and receive data layed out a device dependent +way. The +.Nm +library contains routines to extract the +.Em report descriptor +which contains the data layout information and then use this information. +.Pp +The routines can be divided into four parts: extraction of the descriptor, +parsing of the descriptor, translating to/from symbolic names, and +data manipulation. +.Ss DESCRIPTOR FUNCTIONS +A report descriptor can be obtained by calling +.Fn hid_get_report_desc +with a file descriptor obtained by opening a +.Xr uhid 4 +device. +When the report descriptor is no longer needed it should be freed +by calling +.Fn hid_dispose_report_desc . +The type +.Fa report_desc_t +is opaque and should be used when calling the parsing functions. +.Ss DESCRIPTOR PARSING FUNCTIONS +To parse the report descriptor the +.Fn hid_start_parse +function should be called with a report descriptor and a set that +describes which items that are interesting. The set is obtained +by oring together values +.Fa "(1 << k)" +where +.Fa k +is an item of type +.Fa hid_kind_t . +The function returns +.Fa NULL +if the initialization fails, otherwise an opaque value to be used +in subsequent calls. +After parsing the +.Fn hid_end_parse +function should be called to free internal data structures. +.Pp +To iterate through all the items in the report descriptor +.Fn hid_get_item +should be called while it returns a value greater than 0. +When the report descriptor ends it will returns 0; a syntax +error within the report descriptor will cause a return value less +than 0. +The struct pointed to by +.Fa h +will be filled with the relevant data for the item. +The definition of +.Fa hid_item_t +can be found in +.Pa <usb.h> +and the meaning of the components in the USB HID documentation. +.Pp +Data should be read/written to the device in the size of +the report. The size of a report (of a certain kind) can be +computed by the +.Fn hid_report_size +function. If the report is prefixed by an ID byte it is +stored at +.Fa idp , +otherwise it will contain 0. +.Pp +To locate a single item the +.Fn hid_locate +function can be used. It should be given the usage code of +the item and its kind and it will fill the item and return +non-zero if the item was found. +.Pp +.Ss NAME TRANSLATION FUNCTIONS +The function +.Fn hid_usage_page +will return the symbolic name of a usage page, and the function +.Fn hid_usage_in_page +will return the symbolic name of the usage within the page. +Both these functions may return a pointer to static data. +Before either of these functions can be called the usage table +must be parsed, this is done by calling +.Fn hid_init +with the name of the table. Passing +.Fa NULL +to this function will cause it to use the default table. +.Ss DATA EXTRACTION FUNCTIONS +Given the data obtained from a HID device and an item in the +report descriptor the +.Fn hid_get_data +function extracts the value of the item. +Conversely +.Fn hid_set_data +can be used to put data into a report (which must be zeroed first). +.Sh EXAMPLE +Not yet. +.Sh FILES +.Pa /usr/share/misc/usb_hid_usages +The default HID usage table. +.Sh BUGS +This man page is woefully incomplete. +.Sh SEE ALSO +The +.Tn USB +specifications can be found at +.Dv http://www.usb.org/developers/docs.htm . +.Pp +.Xr hid 4 , +.Xr usb 4 . +.Sh HISTORY +The +.Nm +library first appeared in +.Nx 1.5 . diff --git a/hw/xfree86/os-support/bsd/libusb/usb.h b/hw/xfree86/os-support/bsd/libusb/usb.h new file mode 100644 index 000000000..69ef79a62 --- /dev/null +++ b/hw/xfree86/os-support/bsd/libusb/usb.h @@ -0,0 +1,95 @@ +/* $NetBSD: usb.h,v 1.5 1999/07/02 15:46:53 simonb Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/libusb/usb.h,v 1.1 2000/02/11 18:06:51 dawes Exp $ */ + +#define _DIAGASSERT(e) assert(e) + +typedef struct report_desc *report_desc_t; + +typedef struct hid_data *hid_data_t; + +typedef enum hid_kind { + hid_input, hid_output, hid_feature, hid_collection, hid_endcollection +}hid_kind_t; + +typedef struct hid_item { + /* Global */ + int _usage_page; + int logical_minimum; + int logical_maximum; + int physical_minimum; + int physical_maximum; + int unit_exponent; + int unit; + int report_size; + int report_ID; + int report_count; + /* Local */ + unsigned int usage; + int usage_minimum; + int usage_maximum; + int designator_index; + int designator_minimum; + int designator_maximum; + int string_index; + int string_minimum; + int string_maximum; + int set_delimiter; + /* Misc */ + int collection; + int collevel; + enum hid_kind kind; + unsigned int flags; + /* Absolute data position (bits) */ + unsigned int pos; + /* */ + struct hid_item *next; +} hid_item_t; + +#define HID_PAGE(u) ((u) >> 16) +#define HID_USAGE(u) ((u) & 0xffff) + +/* Obtaining a report descriptor, descr.c: */ +report_desc_t hid_get_report_desc __P((int file)); +void hid_dispose_report_desc __P((report_desc_t)); + +/* Parsing of a HID report descriptor, parse.c: */ +hid_data_t hid_start_parse __P((report_desc_t d, int kindset)); +void hid_end_parse __P((hid_data_t s)); +int hid_get_item __P((hid_data_t s, hid_item_t *h)); +int hid_report_size __P((report_desc_t d, enum hid_kind k, int *idp)); +int hid_locate __P((report_desc_t d, unsigned int usage, enum hid_kind k, hid_item_t *h)); + +/* Conversion to/from usage names, usage.c: */ +char *hid_usage_page __P((int i)); +char *hid_usage_in_page __P((unsigned int u)); +void hid_init __P((char *file)); + +/* Extracting/insertion of data, data.c: */ +int hid_get_data __P((void *p, hid_item_t *h)); +void hid_set_data __P((void *p, hid_item_t *h, int data)); diff --git a/hw/xfree86/os-support/bsd/libusb/usb_hid_usages b/hw/xfree86/os-support/bsd/libusb/usb_hid_usages new file mode 100644 index 000000000..711ba206a --- /dev/null +++ b/hw/xfree86/os-support/bsd/libusb/usb_hid_usages @@ -0,0 +1,1079 @@ +# $NetBSD: usb_hid_usages,v 1.3 1999/07/02 15:46:53 simonb Exp $ +# +# USB HID usage table +# Syntax: +# - lines that do not start with a white space give the number and name of +# a usage page. +# - lines that start with a white space give the number and name of +# a usage with the last given page. +# If the number is * then the line matches all usages and the name +# is a printf formatting string that will be given the usage number. +# +# $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/libusb/usb_hid_usages,v 1.1 2000/02/11 18:06:51 dawes Exp $ +# +1 Generic Desktop + 0x00 Undefined + 0x01 Pointer + 0x02 Mouse + 0x03 Reserved + 0x04 Joystick + 0x05 Game Pad + 0x06 Keyboard + 0x07 Keypad + 0x08 Multi-axis Controller + 0x30 X + 0x31 Y + 0x32 Z + 0x33 Rx + 0x34 Ry + 0x35 Rz + 0x36 Slider + 0x37 Dial + 0x38 Wheel + 0x39 Hat Switch + 0x3A Counted Buffer + 0x3B Byte Count + 0x3C Motion Wakeup + 0x40 Vx + 0x41 Vy + 0x42 Vz + 0x43 Vbrx + 0x44 Vbry + 0x45 Vbrx + 0x46 Vno + 0x80 System Control + 0x81 System Power Down + 0x82 System Sleep + 0x83 System Wake Up + 0x84 System Context Menu + 0x85 System Main Menu + 0x86 System App Menu + 0x87 System Menu Help + 0x88 System Menu Exit + 0x89 System Menu Select + 0x8A System Menu Right + 0x8B System Menu Left + 0x8C System Menu Up + 0x8D System Menu Down + 0x90 D-pad Up + 0x91 D-pad Down + 0x92 D-pad Right + 0x93 D-pad Left + +2 Simulation Controls + 0x00 Undefined + 0x01 Flight Simulation Device + 0x02 Automobile Simulation Device + 0x03 Tank Simulation Device + 0x04 Spaceship Simulation Device + 0x05 Submarine Simulation Device + 0x06 Sailing Simulation Device + 0x07 Motorcycle Simulation Device + 0x08 Sports Simulation Device + 0x09 Airplane Simulation Device + 0x0A Helicopter Simulation Device + 0x0B Magic Carpet Simulation Device + 0x0C Bicycle + 0x20 Flight Control Stick + 0x21 Flight Stick + 0x22 Cyclic Control + 0x23 Cyclic Trim + 0x24 Flight Yoke + 0x25 Track Control + 0x26 Driving Control + 0xB0 Aileron + 0xB1 Aileron Trim + 0xB2 Anti-Torque Control + 0xB3 Auto-pilot Enable + 0xB4 Chaff Release + 0xB5 Collective Control + 0xB6 Dive Brake + 0xB7 Electronic Counter Measures + 0xB8 Elevator + 0xB9 Elevator Trim + 0xBA Rudder + 0xBB Throttle + 0xBC Flight Communication + 0xBD Flare Release + 0xBE Landing Gear + 0xBF Toe Brake + 0xC0 Trigger + 0xC1 Weapons Arm + 0xC2 Weapons Select + 0xC3 Wing Flaps + 0xC4 Accelerator + 0xC5 Brake + 0xC6 Clutch + 0xC7 Shifter + 0xC8 Steering + 0xC9 Turret Direction + 0xCA Barrel Elevation + 0xCB Dive Plane + 0xCC Ballast + 0xCD Bicycle Crank + 0xCE Handle Bars + 0xCF Front Brake + 0xD0 Rear Brake + +3 VR Controls + 0x00 Unidentified + 0x01 Belt + 0x02 Body Suit + 0x03 Flexor + 0x04 Glove + 0x05 Head Tracker + 0x06 Head Mounted Display + 0x07 Hand Tracker + 0x08 Oculometer + 0x09 Vest + 0x0A Animatronic Device + 0x20 Stereo Enable + 0x21 Display Enable + +4 Sports Controls + 0x00 Unidentified + 0x01 Baseball Bat + 0x02 Golf Club + 0x03 Rowing Machine + 0x04 Treadmill + 0x30 Oar + 0x31 Slope + 0x32 Rate + 0x33 Stick Speed + 0x34 Stick Face Angle + 0x35 Stick Heel/Toe + 0x36 Stick Follow Through + 0x37 Stick Tempo + 0x38 Stick Type + 0x39 Stick Height + 0x50 Putter + 0x51 1 Iron + 0x52 2 Iron + 0x53 3 Iron + 0x54 4 Iron + 0x55 5 Iron + 0x56 6 Iron + 0x57 7 Iron + 0x58 8 Iron + 0x59 9 Iron + 0x5A 10 Iron + 0x5B 11 Iron + 0x5C Sand Wedge + 0x5D Loft Wedge + 0x5E Power Wedge + 0x5F 1 Wood + 0x60 3 Wood + 0x61 5 Wood + 0x62 7 Wood + 0x63 9 Wood + +5 Game Controls + 0x00 Undefined + 0x01 3D Game Controller + 0x02 Pinball Device + 0x03 Gun Device + 0x20 Point of View + 0x21 Turn Right/Left + 0x22 Pitch Right/Left + 0x23 Roll Forward/Backward + 0x24 Move Right/Left + 0x25 Move Forward/Backward + 0x26 Move Up/Down + 0x27 Lean Right/Left + 0x28 Lean Forward/Backward + 0x29 Height of POV + 0x2A Flipper + 0x2B Secondary Flipper + 0x2C Bump + 0x2D New Game + 0x2E Shoot Ball + 0x2F Player + 0x30 Gun Bolt + 0x31 Gun Clip + 0x32 Gun Selector + 0x33 Gun Single Shot + 0x34 Gun Burst + 0x35 Gun Automatic + 0x36 Gun Safety + 0x37 Gamepad Fire/Jump + 0x39 Gamepad Trigger + +7 Keyboard + 0x00 Reserved (no event indicated) + 0x01 Keyboard ErrorRollOver + 0x02 Keyboard POSTFail + 0x03 Keyboard ErrorUndefined + 0x04 Keyboard a and A + 0x05 Keyboard b and B + 0x06 Keyboard c and C + 0x07 Keyboard d and D + 0x08 Keyboard e and E + 0x09 Keyboard f and F + 0x0A Keyboard g and G + 0x0B Keyboard h and H + 0x0C Keyboard i and I + 0x0D Keyboard j and J + 0x0E Keyboard k and K + 0x0F Keyboard l and L + 0x10 Keyboard m and M + 0x11 Keyboard n and N + 0x12 Keyboard o and O + 0x13 Keyboard p and P + 0x14 Keyboard q and Q + 0x15 Keyboard r and R + 0x16 Keyboard s and S + 0x17 Keyboard t and T + 0x18 Keyboard u and U + 0x19 Keyboard v and V + 0x1A Keyboard w and W + 0x1B Keyboard x and X + 0x1C Keyboard y and Y + 0x1D Keyboard z and Z + 0x1E Keyboard 1 and ! + 0x1F Keyboard 2 and @ + 0x20 Keyboard 3 and # + 0x21 Keyboard 4 and $ + 0x22 Keyboard 5 and % + 0x23 Keyboard 6 and ^ + 0x24 Keyboard 7 and & + 0x25 Keyboard 8 and * + 0x26 Keyboard 9 and ( + 0x27 Keyboard 0 and ) + 0x28 Keyboard Return (ENTER) + 0x29 Keyboard ESCAPE + 0x2A Keyboard DELETE (Backspace) + 0x2B Keyboard Tab + 0x2C Keyboard Spacebar + 0x2D Keyboard - and (underscore) + 0x2E Keyboard = and + + 0x2F Keyboard [ and { + 0x30 Keyboard ] and } + 0x31 Keyboard \ and | + 0x32 Keyboard Non-US # and ~ + 0x33 Keyboard ; and : + 0x34 Keyboard ' and " + 0x35 Keyboard Grave Accent and Tilde + 0x36 Keyboard, and < + 0x37 Keyboard . and > + 0x38 Keyboard / and ? + 0x39 Keyboard Caps Lock + 0x3A Keyboard F1 + 0x3B Keyboard F2 + 0x3C Keyboard F3 + 0x3D Keyboard F4 + 0x3E Keyboard F5 + 0x3F Keyboard F6 + 0x40 Keyboard F7 + 0x41 Keyboard F8 + 0x42 Keyboard F9 + 0x43 Keyboard F10 + 0x44 Keyboard F11 + 0x45 Keyboard F12 + 0x46 Keyboard PrintScreen + 0x47 Keyboard Scroll Lock + 0x48 Keyboard Pause + 0x49 Keyboard Insert + 0x4A Keyboard Home + 0x4B Keyboard PageUp + 0x4C Keyboard Delete Forward + 0x4D Keyboard End + 0x4E Keyboard PageDown + 0x4F Keyboard RightArrow + 0x50 Keyboard LeftArrow + 0x51 Keyboard DownArrow + 0x52 Keyboard UpArrow + 0x53 Keypad Num Lock and Clear + 0x54 Keypad / + 0x55 Keypad * + 0x56 Keypad - + 0x57 Keypad + + 0x58 Keypad ENTER + 0x59 Keypad 1 and End + 0x5A Keypad 2 and Down Arrow + 0x5B Keypad 3 and PageDn + 0x5C Keypad 4 and Left Arrow + 0x5D Keypad 5 + 0x5E Keypad 6 and Right Arrow + 0x5F Keypad 7 and Home + 0x60 Keypad 8 and Up Arrow + 0x61 Keypad 9 and PageUp + 0x62 Keypad 0 and Insert + 0x63 Keypad . and Delete + 0x64 Keyboard Non-US \ and | + 0x65 Keyboard Application + 0x66 Keyboard Power + 0x67 Keypad = + 0x68 Keyboard F13 + 0x69 Keyboard F14 + 0x6A Keyboard F15 + 0x6B Keyboard F16 + 0x6C Keyboard F17 + 0x6D Keyboard F18 + 0x6E Keyboard F19 + 0x6F Keyboard F20 + 0x70 Keyboard F21 + 0x71 Keyboard F22 + 0x72 Keyboard F23 + 0x73 Keyboard F24 + 0x74 Keyboard Execute + 0x75 Keyboard Help + 0x76 Keyboard Menu + 0x77 Keyboard Select + 0x78 Keyboard Stop + 0x79 Keyboard Again + 0x7A Keyboard Undo + 0x7B Keyboard Cut + 0x7C Keyboard Copy + 0x7D Keyboard Paste + 0x7E Keyboard Find + 0x7F Keyboard Mute + 0x80 Keyboard Volume Up + 0x81 Keyboard Volume Down + 0x82 Keyboard Locking Caps Lock + 0x83 Keyboard Locking Num Lock + 0x84 Keyboard Locking Scroll Lock + 0x85 Keypad Comma + 0x86 Keypad Equal Sign + 0x87 Keyboard International1 + 0x88 Keyboard International2 + 0x89 Keyboard International3 + 0x8A Keyboard International4 + 0x8B Keyboard International5 + 0x8C Keyboard International6 + 0x8D Keyboard International7 + 0x8E Keyboard International8 + 0x8F Keyboard International9 + 0x90 Keyboard LANG1 + 0x91 Keyboard LANG2 + 0x92 Keyboard LANG3 + 0x93 Keyboard LANG4 + 0x94 Keyboard LANG5 + 0x95 Keyboard LANG6 + 0x96 Keyboard LANG7 + 0x97 Keyboard LANG8 + 0x98 Keyboard LANG9 + 0x99 Keyboard Alternate Erase + 0x9A Keyboard SysReq/Attention + 0x9B Keyboard Cancel + 0x9C Keyboard Clear + 0x9D Keyboard Prior + 0x9E Keyboard Return + 0x9F Keyboard Separator + 0xA0 Keyboard Out + 0xA1 Keyboard Oper + 0xA2 Keyboard Clear/Again + 0xA3 Keyboard CrSel/Props + 0xA4 Keyboard ExSel + 0xE0 Keyboard LeftControl + 0xE1 Keyboard LeftShift + 0xE2 Keyboard LeftAlt + 0xE3 Keyboard Left GUI + 0xE4 Keyboard RightControl + 0xE5 Keyboard RightShift + 0xE6 Keyboard RightAlt + 0xE7 Keyboard Right GUI + +8 LEDs + 0x00 Undefined + 0x01 Num Lock + 0x02 Caps Lock + 0x03 Scroll Lock + 0x04 Compose + 0x05 Kana + 0x06 Power + 0x07 Shift + 0x08 Do Not Disturb + 0x09 Mute + 0x0A Tone Enable + 0x0B High Cut Filter + 0x0C Low Cut Filter + 0x0D Equalizer Enable + 0x0E Sound Field On + 0x0F Surround Field On + 0x10 Repeat + 0x11 Stereo + 0x12 Sampling Rate Detect + 0x13 Spinning + 0x14 CAV + 0x15 CLV + 0x16 Recording Format Detect + 0x17 Off-Hook + 0x18 Ring + 0x19 Message Waiting + 0x1A Data Mode + 0x1B Battery Operation + 0x1C Battery OK + 0x1D Battery Low + 0x1E Speaker + 0x1F Head Set + 0x20 Hold + 0x21 Microphone + 0x22 Coverage + 0x23 Night Mode + 0x24 Send Calls + 0x25 Call Pickup + 0x26 Conference + 0x27 Stand-by + 0x28 Camera On + 0x29 Camera Off + 0x2A On-Line + 0x2B Off-Line + 0x2C Busy + 0x2D Ready + 0x2E Paper-Out + 0x2F Paper-Jam + 0x30 Remote + 0x31 Forward + 0x32 Reverse + 0x33 Stop + 0x34 Rewind + 0x35 Fast Forward + 0x36 Play + 0x37 Pause + 0x38 Record + 0x39 Error + 0x3A Usage Selected Indicator + 0x3B Usage In Use Indicator + 0x3C Usage Multi Mode Indicator + 0x3D Indicator On + 0x3E Indicator Flash + 0x3F Indicator Slow Blink + 0x40 Indicator Fast Blink + 0x41 Indicator Off + 0x42 Flash On Time + 0x43 Slow Blink On Time + 0x44 Slow Blink Off Time + 0x45 Fast Blink On Time + 0x46 Fast Blink Off Time + 0x47 Usage Indicator Color + 0x48 Red + 0x49 Green + 0x4A Amber + 0x4B Generic Indicator + 0x4C System Suspend + 0x4D External Power Connected + 0x4C-FFFF Reserved + +9 Button + 0x00 No Button Pressed + * Button %d + +10 Ordinal + 0x00 Unused + * Instance %d + +11 Telephony + 0x00 Unassigned + 0x01 Phone + 0x02 Answering Machine + 0x03 Message Controls + 0x04 Handset + 0x05 Headset + 0x06 Telephony Key Pad + 0x07 Programmable Button + 0x20 Hook Switch + 0x21 Flash + 0x22 Feature + 0x23 Hold + 0x24 Redial + 0x25 Transfer + 0x26 Drop + 0x27 Park + 0x28 Forward Calls + 0x29 Alternate Function + 0x2A Line + 0x2B Speaker Phone + 0x2C Conference + 0x2D Ring Enable + 0x2E Ring Select + 0x2F Phone Mute + 0x30 Caller ID + 0x50 Speed Dial + 0x51 Store Number + 0x52 Recall Number + 0x53 Phone Directory + 0x70 Voice Mail + 0x71 Screen Calls + 0x72 Do Not Disturb + 0x73 Message + 0x74 Answer On/Off + 0x90 Inside Dial Tone + 0x91 Outside Dial Tone + 0x92 Inside Ring Tone + 0x93 Outside Ring Tone + 0x94 Priority Ring Tone + 0x95 Inside Ringback + 0x96 Priority Ringback + 0x97 Line Busy Tone + 0x98 Reorder Tone + 0x99 Call Waiting Tone + 0x9A Confirmation Tone 1 + 0x9B Confirmation Tone 2 + 0x9C Tones Off + 0xB0 Phone Key 0 + 0xB1 Phone Key 1 + 0xB2 Phone Key 2 + 0xB3 Phone Key 3 + 0xB4 Phone Key 4 + 0xB5 Phone Key 5 + 0xB6 Phone Key 6 + 0xB7 Phone Key 7 + 0xB8 Phone Key 8 + 0xB9 Phone Key 9 + 0xBA Phone Key Star + 0xBB Phone Key Pound + 0xBC Phone Key A + 0xBD Phone Key B + 0xBE Phone Key C + 0xBF Phone Key D + +12 Consumer + 0x00 Unassigned + 0x01 Consumer Control + 0x02 Numeric Key Pad + 0x03 Programmable Buttons + 0x20 +10 + 0x21 +100 + 0x22 AM/PM + 0x30 Power + 0x31 Reset + 0x32 Sleep + 0x33 Sleep After + 0x34 Sleep Mode + 0x35 Illumination + 0x36 Function Buttons + 0x40 Menu + 0x41 Menu Pick + 0x42 Menu Up + 0x43 Menu Down + 0x44 Menu Left + 0x45 Menu Right + 0x46 Menu Escape + 0x47 Menu Value Increase + 0x48 Menu Value Decrease + 0x60 Data On Screen + 0x61 Closed Caption + 0x62 Closed Caption Select + 0x63 VCR/TV + 0x64 Broadcast Mode + 0x65 Snapshot + 0x66 Still + 0x80 Selection + 0x81 Assign Selection + 0x82 Mode Step + 0x83 Recall Last + 0x84 Enter Channel + 0x85 Order Movie + 0x86 Channel + 0x87 Media Selection + 0x88 Media Select Computer + 0x89 Media Select TV + 0x8A Media Select WWW + 0x8B Media Select DVD + 0x8C Media Select Telephone + 0x8D Media Select Program Guide + 0x8E Media Select Video Phone + 0x8F Media Select Games + 0x90 Media Select Messages + 0x91 Media Select CD + 0x92 Media Select VCR + 0x93 Media Select Tuner + 0x94 Quit + 0x95 Help + 0x96 Media Select Tape + 0x97 Media Select Cable + 0x98 Media Select Satellite + 0x99 Media Select Security + 0x9A Media Select Home + 0x9B Media Select Call + 0x9C Channel Increment + 0x9D Channel Decrement + 0x9E Media Select SAP + 0xA0 VCR Plus + 0xA1 Once + 0xA2 Daily + 0xA3 Weekly + 0xA4 Monthly + 0xB0 Play + 0xB1 Pause + 0xB2 Record + 0xB3 Fast Forward + 0xB4 Rewind + 0xB5 Scan Next Track + 0xB6 Scan Previous Track + 0xB7 Stop + 0xB8 Eject + 0xB9 Random Play + 0xBA Select DisC + 0xBB Enter Disc + 0xBC Repeat + 0xBD Tracking + 0xBE Track Normal + 0xBF Slow Tracking + 0xC0 Frame Forward + 0xC1 Frame Back + 0xC2 Mark + 0xC3 Clear Mark + 0xC4 Repeat From Mark + 0xC5 Return To Mark + 0xC6 Search Mark Forward + 0xC7 Search Mark Backwards + 0xC8 Counter Reset + 0xC9 Show Counter + 0xCA Tracking Increment + 0xCB Tracking Decrement + 0xE0 Volume + 0xE1 Balance + 0xE2 Mute + 0xE3 Bass + 0xE4 Treble + 0xE5 Bass Boost + 0xE6 Surround Mode + 0xE7 Loudness + 0xE8 MPX + 0xE9 Volume Up + 0xEA Volume Down + 0xF0 Speed Select + 0xF1 Playback Speed + 0xF2 Standard Play + 0xF3 Long Play + 0xF4 Extended Play + 0xF5 Slow + 0x100 Fan Enable + 0x101 Fan Speed + 0x102 Light + 0x103 Light Illumination Level + 0x104 Climate Control Enable + 0x105 Room Temperature + 0x106 Security Enable + 0x107 Fire Alarm + 0x108 Police Alarm + 0x150 Balance Right + 0x151 Balance Left + 0x152 Bass Increment + 0x153 Bass Decrement + 0x154 Treble Increment + 0x155 Treble Decrement + 0x160 Speaker System + 0x161 Channel Left + 0x162 Channel Right + 0x163 Channel Center + 0x164 Channel Front + 0x165 Channel Center Front + 0x166 Channel Side + 0x167 Channel Surround + 0x168 Channel Low Frequency Enhancement + 0x169 Channel Top + 0x16A Channel Unknown + 0x170 Sub-channel + 0x171 Sub-channel Increment + 0x172 Sub-channel Decrement + 0x173 Alternate Audio Increment + 0x174 Alternate Audio Decrement + 0x180 Application Launch Buttons + 0x181 AL Launch Button Configuration Tool + 0x182 AL Programmable Button Configuration + 0x183 AL Consumer Control Configuration + 0x184 AL Word Processor + 0x185 AL Text Editor + 0x186 AL Spreadsheet + 0x187 AL Graphics Editor + 0x188 AL Presentation App + 0x189 AL Database App + 0x18A AL Email Reader + 0x18B AL Newsreader + 0x18C AL Voicemail + 0x18D AL Contacts/Address Book + 0x18E AL Calendar/Schedule + 0x18F AL Task/Project Manager + 0x190 AL Log/Journal/Timecard + 0x191 AL Checkbook/Finance + 0x192 AL Calculator + 0x193 AL A/V Capture/Playback + 0x194 AL Local Machine Browser + 0x195 AL LAN/WAN Browser + 0x196 AL Internet Browser + 0x197 AL Remote Networking/ISP Connect + 0x198 AL Network Conference + 0x199 AL Network Chat + 0x19A AL Telephony/Dialer + 0x19B AL Logon + 0x19C AL Logoff + 0x19D AL Logon/Logoff + 0x19E AL Terminal Lock/Screensaver + 0x19F AL Control Panel + 0x1A0 AL Command Line Processor/Run + 0x1A1 AL Process/Task Manager + 0x1A2 AL Select Tast/Application + 0x1A3 AL Next Task/Application + 0x1A4 AL Previous Task/Application + 0x1A5 AL Preemptive Halt Task/Application + 0x200 Generic GUI Application Controls + 0x201 AC New + 0x202 AC Open + 0x203 AC Close + 0x204 AC Exit + 0x205 AC Maximize + 0x206 AC Minimize + 0x207 AC Save + 0x208 AC Print + 0x209 AC Properties + 0x21A AC Undo + 0x21B AC Copy + 0x21C AC Cut + 0x21D AC Paste + 0x21E AC Select All + 0x21F AC Find + 0x220 AC Find and Replace + 0x221 AC Search + 0x222 AC Go To + 0x223 AC Home + 0x224 AC Back + 0x225 AC Forward + 0x226 AC Stop + 0x227 AC Refresh + 0x228 AC Previous Link + 0x229 AC Next Link + 0x22A AC Bookmarks + 0x22B AC History + 0x22C AC Subscriptions + 0x22D AC Zoom In + 0x22E AC Zoom Out + 0x22F AC Zoom + 0x230 AC Full Screen View + 0x231 AC Normal View + 0x232 AC View Toggle + 0x233 AC Scroll Up + 0x234 AC Scroll Down + 0x235 AC Scroll + 0x236 AC Pan Left + 0x237 AC Pan Right + 0x238 AC Pan + 0x239 AC New Window + 0x23A AC Tile Horizontally + 0x23B AC Tile Vertically + 0x23C AC Format + +13 Digitizer + 0x00 Undefined + 0x01 Digitizer + 0x02 Pen + 0x03 Light Pen + 0x04 Touch Screen + 0x05 Touch Pad + 0x06 White Board + 0x07 Coordinate Measuring Machine + 0x08 3-D Digitizer + 0x09 Stereo Plotter + 0x0A Articulated Arm + 0x0B Armature + 0x0C Multiple Point Digitizer + 0x0D Free Space Wand + 0x20 Stylus + 0x21 Puck + 0x22 Finger + 0x30 Tip Pressure + 0x31 Barrel Pressure + 0x32 In Range + 0x33 Touch + 0x34 Untouch + 0x35 Tap + 0x36 Quality + 0x37 Data Valid + 0x38 Transducer Index + 0x39 Tablet Function Keys + 0x3A Program Change Keys + 0x3B Battery Strength + 0x3C Invert + 0x3D X Tilt + 0x3E Y Tilt + 0x3F Azimuth + 0x40 Altitude + 0x41 Twist + 0x42 Tip Switch + 0x43 Secondary Tip Switch + 0x44 Barrel Switch + 0x45 Eraser + 0x46 Tablet Pick + +15 Physical Interface Device + +16 Unicode + * Unicode Char u%04x + +20 Alphnumeric Display + 0x00 Undefined + 0x01 Alphanumeric Display + 0x20 Display Attributes Report + 0x21 ASCII Character Set + 0x22 Data Read Back + 0x23 Font Read Back + 0x24 Display Control Report + 0x25 Clear Display + 0x26 Display Enable + 0x27 Screen Saver Delay + 0x28 Screen Saver Enable + 0x29 Vertical Scroll + 0x2A Horizontal Scroll + 0x2B Character Report + 0x2C Display Data + 0x2D Display Status + 0x2E Stat Not Ready + 0x2F Stat Ready + 0x30 Err Not a loadable character + 0x31 Err Font data cannot be read + 0x32 Cursor Position Report + 0x33 Row + 0x34 Column + 0x35 Rows + 0x36 Columns + 0x37 Cursor Pixel Positioning + 0x38 Cursor Mode + 0x39 Cursor Enable + 0x3A Cursor Blink + 0x3B Font Report + 0x3C Font Data + 0x3D Character Width + 0x3E Character Height + 0x3F Character Spacing Horizontal + 0x40 Character Spacing Vertical + 0x41 Unicode Character Set + +128 Monitor + 0x00 Undefined + 0x01 Monitor Control + 0x02 EDID Information + 0x03 VDIF Information + 0x04 VESA Version + 0x05 On Screen Display + 0x06 Auto Size Center + 0x07 Polarity Horz Synch + 0x08 Polarity Vert Synch + 0x09 Sync Type + 0x0A Screen Position + 0x0B Horizontal Frequency + 0x0C Vertical Frequency + +129 Monitor Enumerated Values + 0x00 unassigned + * ENUM %d + +130 VESA Virtual Controls + 0x10 Brightness + 0x12 Contrast + 0x16 Video Gain Red + 0x18 Video Gain Green + 0x1A Video Gain Blue + 0x1C Focus + 0x20 Horizontal Position + 0x22 Horizontal Size + 0x24 Horizontal Pincushion + 0x26 Horizontal Pincushion Balance + 0x28 Horizontal Misconvergence + 0x2A Horizontal Linearity + 0x2C Horizontal Linearity Balance + 0x30 Vertical Position + 0x32 Vertical Size + 0x34 Vertical Pincushion + 0x36 Vertical Pincushion Balance + 0x38 Vertical Misconvergence + 0x3A Vertical Linearity + 0x3C Vertical Linearity Balance + 0x40 Parallelogram Distortion + 0x42 Trapezoidal Distortion + 0x44 Tilt + 0x46 Top Corner Distortion Control + 0x48 Top Corner Distortion Balance + 0x4A Bottom Corner Distortion Control + 0x4C Bottom Corner Distortion Balance + 0x56 Moiré Horizontal + 0x58 Moiré Vertical + 0x5E Input Level Select + 0x60 Input Source Select + 0x62 Stereo Mode + 0x6C Video Black Level Red + 0x6E Video Black Level Green + 0x70 Video Black Level Blue + +131 VESA Command + 0x00 Undefined + 0x01 Settings + 0x02 Degauss + +132 Power Device + 0x00 Undefined + 0x01 iName + 0x02 PresentStatus + 0x03 ChangedStatus + 0x04 UPS + 0x05 PowerSupply + 0x10 BatterySystem + 0x11 BatterySystemID + 0x12 Battery + 0x13 BatteryID + 0x14 Charger + 0x15 ChargerID + 0x16 PowerConverter + 0x17 PowerConverterID + 0x18 OutletSystem + 0x19 OutletSystemID + 0x1A Input + 0x1B InputID + 0x1C Output + 0x1D OutputID + 0x1E Flow + 0x1F FlowID + 0x20 Outlet + 0x21 OutletID + 0x22 Gang + 0x23 GangID + 0x24 Sink + 0x25 SinkID + 0x30 Voltage + 0x31 Current + 0x32 Frequency + 0x33 ApparentPower + 0x34 ActivePower + 0x35 PercentLoad + 0x36 Temperature + 0x37 Humidity + 0x40 ConfigVoltage + 0x41 ConfigCurrent + 0x42 ConfigFrequency + 0x43 ConfigApparentPower + 0x44 ConfigActivePower + 0x45 ConfigPercentLoad + 0x46 ConfigTemperature + 0x47 ConfigHumidity + 0x50 SwitchOnControl + 0x51 SwitchOffControl + 0x52 ToggleControl + 0x53 LowVoltageTransfer + 0x54 HighVoltageTransfer + 0x55 DelayBeforeReboot + 0x56 DelayBeforeStartup + 0x57 DelayBeforeShutdown + 0x58 Test + 0x59 Vendorspecificcommand + 0x60 Present + 0x61 Good + 0x62 InternalFailure + 0x63 VoltageOutOfRange + 0x64 FrequencyOutOfRange + 0x65 Overload + 0x66 OverCharged + 0x67 OverTemperature + 0x68 ShutdownRequested + 0x69 ShutdownImminent + 0x6A VendorSpecificAnswerValid + 0x6B SwitchOn/Off + 0x6C Switcheble + 0x6D Used + 0x6E Boost + 0x6F Buck + 0x70 Initialized + 0x71 Tested + +133 Battery System + 0x00 Undefined + 0x01 SMBBatteryMode + 0x02 SMBBatteryStatus + 0x03 SMBAlarmWarning + 0x04 SMBChargerMode + 0x05 SMBChargerStatus + 0x06 SMBChargerSpecInfo + 0x07 SMBSelectorState + 0x08 SMBSelectorPreset + 0x09 SMBSelectorInfo + 0x10 OptionalMfgFunction1 + 0x11 OptionalMfgFunction2 + 0x12 OptionalMfgFunction3 + 0x13 OptionalMfgFunction4 + 0x14 OptionalMfgFunction5 + 0x15 ConnectionToSMBus + 0x16 OutputConnection + 0x17 ChargerConnection + 0x18 BatteryInsertion + 0x19 Usenext + 0x1A OKToUse + 0x28 ManufacturerAccess + 0x29 RemainingCapacityLimit + 0x2A RemainingTimeLimit + 0x2B AtRate + 0x2C CapacityMode + 0x2D BroadcastToCharger + 0x2E PrimaryBattery + 0x2F ChargeController + 0x40 TerminateCharge + 0x41 TermminateDischarge + 0x42 BelowRemainingCapacityLimit + 0x43 RemainingTimeLimitExpired + 0x44 Charging + 0x45 Discharging + 0x46 FullyCharged + 0x47 FullyDischarged + 0x48 ConditionningFlag + 0x49 AtRateOK + 0x4A SMBErrorCode + 0x4B NeedReplacement + 0x60 AtRateTimeToFull + 0x61 AtRateTimeToEmpty + 0x62 AverageCurrent + 0x63 Maxerror + 0x64 RelativeStateOfCharge + 0x65 AbsoluteStateOfCharge + 0x66 RemainingCapacity + 0x67 FullChargeCapacity + 0x68 RunTimeToEmpty + 0x69 AverageTimeToEmpty + 0x6A AverageTimeToFull + 0x6B CycleCount + 0x80 BattPackModelLevel + 0x81 InternalChargeController + 0x82 PrimaryBatterySupport + 0x83 DesignCapacity + 0x84 SpecificationInfo + 0x85 ManufacturerDate + 0x86 SerialNumber + 0x87 iManufacturerName + 0x88 iDevicename + 0x89 iDeviceChemistery + 0x8A iManufacturerData + 0x8B Rechargeable + 0x8C WarningCapacityLimit + 0x8D CapacityGranularity1 + 0x8E CapacityGranularity2 + 0xC0 InhibitCharge + 0xC1 EnablePolling + 0xC2 ResetToZero + 0xD0 ACPresent + 0xD1 BatteryPresent + 0xD2 PowerFail + 0xD3 AlarmInhibited + 0xD4 ThermistorUnderRange + 0xD5 ThermistorHot + 0xD6 ThermistorCold + 0xD7 ThermistorOverRange + 0xD8 VoltageOutOfRange + 0xD9 CurrentOutOfRange + 0xDA CurrentNotRegulated + 0xDB VoltageNotRegulated + 0xDC MasterMode + 0xDD ChargerBattery/HostControlled + 0xF0 ChargerSpecInfo + 0xF1 ChargerSpecRef + 0xF2 Level2 + 0xF3 Level3 + +140 Bar Code Scanner + +141 Scale Device + +144 Camera Control + +145 Arcade Device + +# Some Micro$oft non-standard extensions +0xff00 Microsoft + 0xe9 Base Up + 0xea Base Down diff --git a/hw/xfree86/os-support/bsd/libusb/usbvar.h b/hw/xfree86/os-support/bsd/libusb/usbvar.h new file mode 100644 index 000000000..cb0bf33ec --- /dev/null +++ b/hw/xfree86/os-support/bsd/libusb/usbvar.h @@ -0,0 +1,34 @@ +/* $NetBSD: usbvar.h,v 1.2 1999/05/11 21:15:46 augustss Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson <augustss@netbsd.org> + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/libusb/usbvar.h,v 1.1 2000/02/11 18:06:51 dawes Exp $ */ + +struct report_desc { + unsigned int size; + unsigned char data[1]; +}; + diff --git a/hw/xfree86/os-support/bsd/memrange.h b/hw/xfree86/os-support/bsd/memrange.h new file mode 100644 index 000000000..99be9ea2f --- /dev/null +++ b/hw/xfree86/os-support/bsd/memrange.h @@ -0,0 +1,68 @@ +/* + * Memory range attribute operations, peformed on /dev/mem + * + * $FreeBSD: src/sys/sys/memrange.h,v 1.4 1999/12/29 04:24:44 peter Exp $ + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/memrange.h,v 1.1 2002/08/06 13:25:36 herrb Exp $ */ + +#ifndef _MEMRANGE_H +#define _MEMRANGE_H + +/* Memory range attributes */ +#define MDF_UNCACHEABLE (1<<0) /* region not cached */ +#define MDF_WRITECOMBINE (1<<1) /* region supports "write combine" + * action */ +#define MDF_WRITETHROUGH (1<<2) /* write-through cached */ +#define MDF_WRITEBACK (1<<3) /* write-back cached */ +#define MDF_WRITEPROTECT (1<<4) /* read-only region */ +#define MDF_ATTRMASK (0x00ffffff) + +#define MDF_FIXBASE (1<<24) /* fixed base */ +#define MDF_FIXLEN (1<<25) /* fixed length */ +#define MDF_FIRMWARE (1<<26) /* set by firmware (XXX not useful?) */ +#define MDF_ACTIVE (1<<27) /* currently active */ +#define MDF_BOGUS (1<<28) /* we don't like it */ +#define MDF_FIXACTIVE (1<<29) /* can't be turned off */ +#define MDF_BUSY (1<<30) /* range is in use */ + +struct mem_range_desc { + u_int64_t mr_base; + u_int64_t mr_len; + int mr_flags; + char mr_owner[8]; +}; + +struct mem_range_op { + struct mem_range_desc *mo_desc; + int mo_arg[2]; +#define MEMRANGE_SET_UPDATE 0 +#define MEMRANGE_SET_REMOVE 1 + /* XXX want a flag that says "set and undo when I exit" */ +}; +#define MEMRANGE_GET _IOWR('m', 50, struct mem_range_op) +#define MEMRANGE_SET _IOW('m', 51, struct mem_range_op) + +#ifdef _KERNEL + +struct mem_range_softc; +struct mem_range_ops { + void (*init) __P((struct mem_range_softc * sc)); + int (*set) __P((struct mem_range_softc * sc, struct mem_range_desc * mrd, int *arg)); + void (*initAP) __P((struct mem_range_softc * sc)); +}; + +struct mem_range_softc { + struct mem_range_ops *mr_op; + int mr_cap; + int mr_ndesc; + struct mem_range_desc *mr_desc; +}; + +extern struct mem_range_softc mem_range_softc; + +extern int mem_range_attr_get __P((struct mem_range_desc * mrd, int *arg)); +extern int mem_range_attr_set __P((struct mem_range_desc * mrd, int *arg)); +extern void mem_range_AP_init __P((void)); +#endif + +#endif diff --git a/hw/xfree86/os-support/bsd/ppc_video.c b/hw/xfree86/os-support/bsd/ppc_video.c new file mode 100644 index 000000000..4ec7045e8 --- /dev/null +++ b/hw/xfree86/os-support/bsd/ppc_video.c @@ -0,0 +1,130 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/ppc_video.c,v 1.3 2002/11/09 17:28:08 herrb Exp $ */ +/* + * Copyright 1992 by Rich Murphey <Rich@Rice.edu> + * 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 Rich Murphey and David Wexelblat + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. Rich Murphey and + * David Wexelblat make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RICH MURPHEY 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. + * + */ + +/* $XConsortium: bsd_video.c /main/10 1996/10/25 11:37:57 kaleb $ */ + +#include "X.h" +#include "xf86.h" +#include "xf86Priv.h" + +#include "xf86_OSlib.h" +#include "xf86OSpriv.h" + +#include "bus/Pci.h" + +#ifndef MAP_FAILED +#define MAP_FAILED ((caddr_t)-1) +#endif + + +/***************************************************************************/ +/* Video Memory Mapping section */ +/***************************************************************************/ + +#define DEV_MEM "/dev/mem" + +static pointer ppcMapVidMem(int, unsigned long, unsigned long, int flags); +static void ppcUnmapVidMem(int, pointer, unsigned long); + +void +xf86OSInitVidMem(VidMemInfoPtr pVidMem) +{ + pVidMem->linearSupported = TRUE; + pVidMem->mapMem = ppcMapVidMem; + pVidMem->unmapMem = ppcUnmapVidMem; + pVidMem->initialised = TRUE; +} + + +volatile unsigned char *ioBase = MAP_FAILED; + +static pointer +ppcMapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags) +{ + int fd = xf86Info.screenFd; + pointer base; +#ifdef DEBUG + xf86MsgVerb(X_INFO, 3, "mapVidMem %lx, %lx, fd = %d", + Base, Size, fd); +#endif + + base = mmap(0, Size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, Base); + if (base == MAP_FAILED) + FatalError("%s: could not mmap screen [s=%x,a=%x] (%s)\n", + "xf86MapVidMem", Size, Base, strerror(errno)); + + return base; +} + +static void +ppcUnmapVidMem(int ScreenNum, pointer Base, unsigned long Size) +{ + munmap(Base, Size); +} + +int +xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf, + int Len) +{ + int rv; + static int kmem = -1; + + if (kmem == -1) { + kmem = open("/dev/xf86", 2); + if (kmem == -1) { + FatalError("xf86ReadBIOS: open /dev/xf86\n"); + } + } + +#ifdef DEBUG + xf86MsgVerb(X_INFO, 3, "xf86ReadBIOS() %lx %lx, %x\n", + Base, Offset, Len); +#endif + + + lseek(kmem, Base + Offset, 0); + rv = read(kmem, Buf, Len); + + return rv; +} + +/***************************************************************************/ +/* Interrupt Handling section */ +/***************************************************************************/ + +Bool +xf86DisableInterrupts() +{ + + return(TRUE); +} + +void +xf86EnableInterrupts() +{ + + return; +} diff --git a/hw/xfree86/os-support/bsd/sparc64_video.c b/hw/xfree86/os-support/bsd/sparc64_video.c new file mode 100644 index 000000000..877550154 --- /dev/null +++ b/hw/xfree86/os-support/bsd/sparc64_video.c @@ -0,0 +1,106 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bsd/sparc64_video.c,v 1.1 2002/08/06 13:08:39 herrb Exp $ */ +/* + * Copyright 1992 by Rich Murphey <Rich@Rice.edu> + * 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 Rich Murphey and David Wexelblat + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. Rich Murphey and + * David Wexelblat make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO + * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL RICH MURPHEY 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. + * + */ + + +/* $XConsortium: bsd_video.c /main/10 1996/10/25 11:37:57 kaleb $ */ + +#include "X.h" +#include "xf86.h" +#include "xf86Priv.h" + +#include "xf86_OSlib.h" +#include "xf86OSpriv.h" + +#ifndef MAP_FAILED +#define MAP_FAILED ((caddr_t)-1) +#endif + +/***************************************************************************/ +/* Video Memory Mapping section */ +/***************************************************************************/ + +static pointer sparc64MapVidMem(int, unsigned long, unsigned long, int); +static void sparc64UnmapVidMem(int, pointer, unsigned long); + +void +xf86OSInitVidMem(VidMemInfoPtr pVidMem) +{ + pVidMem->linearSupported = TRUE; + pVidMem->mapMem = sparc64MapVidMem; + pVidMem->unmapMem = sparc64UnmapVidMem; + pVidMem->initialised = TRUE; +} + +static pointer +sparc64MapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, + int flags) +{ + int fd = xf86Info.screenFd; + pointer base; + +#ifdef DEBUG + xf86MsgVerb(X_INFO, 3, "mapVidMem %lx, %lx, fd = %d", + Base, Size, fd); +#endif + + base = mmap(0, Size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, Base); + if (base == MAP_FAILED) + FatalError("%s: could not mmap screen [s=%x,a=%x] (%s)\n", + "xf86MapVidMem", Size, Base, strerror(errno)); + return base; +} + +static void +sparc64UnmapVidMem(int ScreenNum, pointer Base, unsigned long Size) +{ + munmap(Base, Size); +} + +int +xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf, + int Len) +{ + + return (0); +} + +/***************************************************************************/ +/* Interrupt Handling section */ +/***************************************************************************/ + +Bool +xf86DisableInterrupts() +{ + + return(TRUE); +} + +void +xf86EnableInterrupts() +{ + + return; +} diff --git a/hw/xfree86/os-support/bus/460gxPCI.c b/hw/xfree86/os-support/bus/460gxPCI.c new file mode 100644 index 000000000..4840fd144 --- /dev/null +++ b/hw/xfree86/os-support/bus/460gxPCI.c @@ -0,0 +1,451 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/460gxPCI.c,v 1.2 2003/01/10 22:05:45 tsi Exp $ */ +/* + * Copyright (C) 2002-2003 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ + +/* + * This file contains the glue necessary for support of Intel's 460GX chipset. + */ + +#include "460gxPCI.h" +#include "xf86.h" +#include "Pci.h" + +/* 460GX register definitions */ +/* SAC at 0:10:0 */ +#define CBN 0x0040 +/* SAC at CBN:0:0 */ +#define DEVNPRES 0x0070 +/* SAC at CBN:1[0-7]:0 */ +#define BUSNO 0x0048 +#define SUBNO 0x0049 +#define VGASE 0x0080 +#define PCIS 0x0084 +#define IOR 0x008C +#define IORD 0x008E /* CBN:10:0 only */ +/* PXB at CBN:1[0-7]:1 */ +#define ERRCMD 0x0046 + +static int cbn_460gx = -1; +static CARD32 cbdevs_460gx = 0; +static CARD16 iord_460gx; +static int busno_460gx[8], subno_460gx[8]; +static CARD8 pcis_460gx[8], ior_460gx[8]; +static CARD8 has_err_460gx[8], err_460gx[8]; +static CARD8 iomap_460gx[16]; /* One for each 4k */ +static pciBusFuncs_t BusFuncs_460gx; + +static pciConfigPtr +Verify460GXBus(int bus) +{ + pciConfigPtr pPCI; + + if ((bus < 0) || (bus >= pciNumBuses) || + !pciBusInfo[bus] || !(pPCI = pciBusInfo[bus]->bridge) || + (pPCI->busnum != cbn_460gx) || (pPCI->funcnum != 0) || + (pPCI->devnum < 0x10) || (pPCI->devnum > 0x17)) + return NULL; + + return pPCI; +} + +/* + * This function is called to emulate the various settings in a P2P or CardBus + * bridge's control register using one of a 460GX's SAC host bridges. + */ +static CARD16 +Control460GXBridge(int bus, CARD16 mask, CARD16 value) +{ + pciConfigPtr pPCI; + PCITAG tag; + CARD16 current = 0; + CARD8 tmp; + + if ((pPCI = Verify460GXBus(bus))) { + /* Start with VGA enablement */ + tmp = pciReadByte(pPCI->tag, VGASE); + if (tmp & 0x01) { + current |= PCI_PCI_BRIDGE_VGA_EN; + if ((mask & PCI_PCI_BRIDGE_VGA_EN) && + !(value & PCI_PCI_BRIDGE_VGA_EN)) + pciWriteByte(pPCI->tag, VGASE, tmp & ~0x01); + } else { + if (mask & value & PCI_PCI_BRIDGE_VGA_EN) + pciWriteByte(pPCI->tag, VGASE, tmp | 0x01); + } + + /* Move on to master abort failure enablement */ + if (has_err_460gx[pPCI->devnum - 0x10]) { + tag = PCI_MAKE_TAG(pPCI->busnum, pPCI->devnum, pPCI->funcnum + 1); + tmp = pciReadByte(tag, ERRCMD); + if (tmp & 0x01) { + current |= PCI_PCI_BRIDGE_MASTER_ABORT_EN; + if ((mask & PCI_PCI_BRIDGE_MASTER_ABORT_EN) && + !(value & PCI_PCI_BRIDGE_MASTER_ABORT_EN)) + pciWriteByte(tag, ERRCMD, tmp & ~0x01); + } else { + if (mask & value & PCI_PCI_BRIDGE_MASTER_ABORT_EN) + pciWriteByte(tag, ERRCMD, tmp | 0x01); + } + } + + /* Put emulation of any other P2P bridge control here */ + } + + return (current & ~mask) | (value & mask); +} + +/* + * Retrieve various bus numbers representing the connections provided by 460GX + * host bridges. + */ +static void +Get460GXBridgeBusses(int bus, int *primary, int *secondary, int *subordinate) +{ + pciConfigPtr pPCI = Verify460GXBus(bus); + int i; + + /* The returned bus numbers are initialised by the caller */ + + if (!pPCI) + return; + + i = pPCI->devnum - 0x10; + + /* These are not modified, so no need to re-read them */ + if (primary) + *primary = pPCI->busnum; + if (secondary) + *secondary = busno_460gx[i]; + if (subordinate) + *subordinate = subno_460gx[i]; +} + +/* Retrieves a list of the resources routed to a host bridge's secondary bus */ +static void +Get460GXBridgeResources(int bus, + pointer *ppIoRes, + pointer *ppMemRes, + pointer *ppPmemRes) +{ + pciConfigPtr pPCI = Verify460GXBus(bus); + resRange range; + unsigned int i, j; + + if (ppIoRes) { + xf86FreeResList(*ppIoRes); + *ppIoRes = NULL; + + if (pPCI) { + for (i = 0; i <= 0x0F; i++) { + if (iomap_460gx[i] != pPCI->devnum) + continue; + + RANGE(range, i << 12, ((i + 1) << 12) - 1, + RANGE_TYPE(ResExcIoBlock, 0)); + *ppIoRes = xf86AddResToList(*ppIoRes, &range, -1); + } + } + } + + if (ppMemRes) { + xf86FreeResList(*ppMemRes); + *ppMemRes = NULL; + + if (pPCI) { + if (!(i = (pPCI->devnum - 0x10))) + j = 127; /* (4GB - 32M) / 32M */ + else + j = pcis_460gx[i - 1] & 0x7F; + + i = pcis_460gx[i] & 0x7F; + if (i < j) { + RANGE(range, i << 25, (j << 25) - 1, + RANGE_TYPE(ResExcMemBlock, 0)); + *ppMemRes = xf86AddResToList(*ppMemRes, &range, -1); + } + } + } + + if (ppPmemRes) { + xf86FreeResList(*ppPmemRes); + *ppPmemRes = NULL; + } +} + +/* + * This checks for, and validates, the presence of the 460GX chipset, and sets + * cbn_460gx to a positive value accordingly. This function returns TRUE if + * the chipset scan is to be stopped, or FALSE if the scan is to move on to the + * next chipset. + */ +Bool +xf86PreScan460GX(void) +{ + pciBusInfo_t *pBusInfo; + PCITAG tag; + CARD32 tmp; + int i, devno; + + /* Bus zero should already be set up */ + if (!(pBusInfo = pciBusInfo[0])) { + cbn_460gx = -1; + return FALSE; + } + + /* First look for a 460GX's primary host bridge */ + tag = PCI_MAKE_TAG(0, 0x10, 0); + if (pciReadLong(tag, PCI_ID_REG) != DEVID(INTEL, 460GX_SAC)) { + cbn_460gx = -1; + return FALSE; + } + + /* Get CBN (Chipset bus number) */ + if (!(cbn_460gx = (unsigned int)pciReadByte(tag, CBN))) { + /* Sanity check failed */ + cbn_460gx = -1; + return TRUE; + } + + if (pciNumBuses <= cbn_460gx) + pciNumBuses = cbn_460gx + 1; + + /* Set up bus CBN */ + if (!pciBusInfo[cbn_460gx]) { + pciBusInfo[cbn_460gx] = xnfalloc(sizeof(pciBusInfo_t)); + *pciBusInfo[cbn_460gx] = *pBusInfo; + } + + tag = PCI_MAKE_TAG(cbn_460gx, 0, 0); + if (pciReadLong(tag, PCI_ID_REG) != DEVID(INTEL, 460GX_SAC)) { + /* Sanity check failed */ + cbn_460gx = -1; + return TRUE; + } + + /* + * Find out which CBN devices the firmware thinks are present. Of these, + * we are only interested in devices 0x10 through 0x17. + */ + cbdevs_460gx = pciReadLong(tag, DEVNPRES); + + for (i = 0, devno = 0x10; devno <= 0x17; i++, devno++) { + tag = PCI_MAKE_TAG(cbn_460gx, devno, 0); + if (pciReadLong(tag, PCI_ID_REG) != DEVID(INTEL, 460GX_SAC)) { + /* Sanity check failed */ + cbn_460gx = -1; + return TRUE; + } + + if (devno == 0x10) + iord_460gx = pciReadWord(tag, IORD); + + busno_460gx[i] = (unsigned int)pciReadByte(tag, BUSNO); + subno_460gx[i] = (unsigned int)pciReadByte(tag, SUBNO); + pcis_460gx[i] = pciReadByte(tag, PCIS); + ior_460gx[i] = pciReadByte(tag, IOR); + + has_err_460gx[i] = err_460gx[i] = 0; /* Insurance */ + + tag = PCI_MAKE_TAG(cbn_460gx, devno, 1); + tmp = pciReadLong(tag, PCI_ID_REG); + switch (tmp) { + case DEVID(INTEL, 460GX_PXB): + case DEVID(INTEL, 460GX_WXB): + if (cbdevs_460gx & (1 << devno)) { + /* Sanity check failed */ + cbn_460gx = -1; + return TRUE; + } + + /* + * XXX I don't have WXB docs, but PCI register dumps indicate that + * the registers we are interested in are consistent with those of + * the PXB. + */ + err_460gx[i] = pciReadByte(tag, ERRCMD); + has_err_460gx[i] = 1; + break; + + case DEVID(INTEL, 460GX_GXB_1): + if (cbdevs_460gx & (1 << devno)) { + /* Sanity check failed */ + cbn_460gx = -1; + return TRUE; + } + + /* + * XXX GXB isn't documented to have an ERRCMD register, nor any + * other means of failing master aborts. For now, assume master + * aborts are always allowed to complete normally. + */ + break; + + default: + if (((CARD16)(tmp + 1U) <= (CARD16)1U) && + (cbdevs_460gx & (1U << devno))) + break; + /* Sanity check failed */ + cbn_460gx = -1; + return TRUE; + } + } + + /* Allow master aborts to complete normally */ + for (i = 0, devno = 0x10; devno <= 0x17; i++, devno++) { + if (!(err_460gx[i] & 0x01)) + continue; + + pciWriteByte(PCI_MAKE_TAG(cbn_460gx, devno, 1), + ERRCMD, err_460gx[i] & ~0x01); + } + + /* + * The 460GX spec says that any access to busses higher than CBN will be + * master-aborted. It seems possible however that this is not the case in + * all 460GX implementations. For now, limit the bus scan to CBN, unless + * we have already found a higher bus number. + */ + for (i = 0; subno_460gx[i] < cbn_460gx; ) { + if (++i < 8) + continue; + + pciMaxBusNum = cbn_460gx + 1; + break; + } + + return TRUE; +} + +/* This does some 460GX-related processing after the PCI bus scan */ +void +xf86PostScan460GX(void) +{ + pciConfigPtr pPCI, *ppPCI; + pciBusInfo_t *pBusInfo; + int i, j, devno; + + if (cbn_460gx <= 0) + return; + + /* Set up our extra bus functions */ + BusFuncs_460gx = *(pciBusInfo[0]->funcs); + BusFuncs_460gx.pciControlBridge = Control460GXBridge; + BusFuncs_460gx.pciGetBridgeBusses = Get460GXBridgeBusses; + BusFuncs_460gx.pciGetBridgeResources = Get460GXBridgeResources; + + /* + * Mark all host bridges so that they are ignored by the upper-level + * xf86GetPciBridgeInfo() function. This marking is later clobbered by the + * tail end of xf86scanpci() for those bridges that actually have bus + * segments associated with them. + */ + ppPCI = xf86scanpci(0); /* Recursion is only apparent */ + while ((pPCI = *ppPCI++)) { + if ((pPCI->pci_base_class == PCI_CLASS_BRIDGE) && + (pPCI->pci_sub_class == PCI_SUBCLASS_BRIDGE_HOST)) + pPCI->businfo = HOST_NO_BUS; + } + + ppPCI = xf86scanpci(0); /* Recursion is only apparent */ + j = 0; + + /* + * Fix up CBN bus linkage. This is somewhat arbitrary. The bridge chosen + * for this must be a CBN device so that bus CBN can be recognised as the + * root segment. It also cannot be any of the bus expanders (devices + * CBN:0x10:0 through CBN:0x17:0 nor any of their functions). For now, we + * chose the SAC host bridge at CBN:0:0. + */ + pBusInfo = pciBusInfo[cbn_460gx]; + pBusInfo->bridge = pciBusInfo[0]->bridge; /* Just in case */ + while ((pPCI = *ppPCI++)) { + if (pPCI->busnum < cbn_460gx) + continue; + if (pPCI->busnum > cbn_460gx) + break; + if (pPCI->devnum < 0) + continue; + if (pPCI->devnum > 0) + break; + if (pPCI->funcnum < 0) + continue; + if (pPCI->funcnum > 0) + break; + + pBusInfo->bridge = pPCI; + pBusInfo->secondary = FALSE; + pBusInfo->primary_bus = cbn_460gx; + break; + } + + for (i = 0, devno = 0x10; devno <= 0x17; i++, devno++) { + /* Restore ERRCMD registers */ + if (err_460gx[i] & 0x01) + pciWriteByte(PCI_MAKE_TAG(cbn_460gx, devno, 1), + ERRCMD, err_460gx[i]); + + if (!(cbdevs_460gx & (1 << devno))) { + while ((pPCI = *ppPCI++)) { + if (pPCI->busnum < cbn_460gx) + continue; + if (pPCI->busnum > cbn_460gx) + break; + if (pPCI->devnum < devno) + continue; + if (pPCI->devnum > devno) + break; + if (pPCI->funcnum < 0) + continue; + if (pPCI->funcnum > 0) + break; + + if ((pBusInfo = pciBusInfo[busno_460gx[i]])) + break; + + /* Fix bus linkage */ + pBusInfo->bridge = pPCI; + pBusInfo->secondary = TRUE; + pBusInfo->primary_bus = cbn_460gx; + + /* Plug in chipset routines */ + pBusInfo->funcs = &BusFuncs_460gx; + break; + } + } + + /* Decode IOR registers */ + for(; j <= (ior_460gx[i] & 0x0F); j++) + iomap_460gx[j] = devno; + } + + /* The bottom 4k of I/O space is always routed to PCI0a */ + iomap_460gx[0] = 0x10; + + /* Decode IORD register */ + for (j = 1; j <= 0x0F; j++) + if (iord_460gx & (1 << j)) + iomap_460gx[j] = 0x10; +} diff --git a/hw/xfree86/os-support/bus/460gxPCI.h b/hw/xfree86/os-support/bus/460gxPCI.h new file mode 100644 index 000000000..2ae9c3528 --- /dev/null +++ b/hw/xfree86/os-support/bus/460gxPCI.h @@ -0,0 +1,36 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/460gxPCI.h,v 1.1 2003/01/02 18:12:48 tsi Exp $ */ +/* + * Copyright (C) 2002-2003 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ + +#ifndef PCI_460GX_H +#define PCI_460GX_H 1 + +#include <X11/Xdefs.h> + +Bool xf86PreScan460GX(void); +void xf86PostScan460GX(void); + +#endif diff --git a/hw/xfree86/os-support/bus/Pci.c b/hw/xfree86/os-support/bus/Pci.c new file mode 100644 index 000000000..c7777827d --- /dev/null +++ b/hw/xfree86/os-support/bus/Pci.c @@ -0,0 +1,1456 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.c,v 1.71.2.2 2003/05/06 17:00:45 tsi Exp $ */ +/* + * Pci.c - New server PCI access functions + * + * The XFree86 server PCI access functions have been reimplemented as a + * framework that allows each supported platform/OS to have their own + * platform/OS specific pci driver. + * + * All of the public PCI access functions exported to the other parts of + * the server are declared in Pci.h and defined herein. These include: + * pciInit() - Initialize PCI access functions + * pciFindFirst() - Find a PCI device by dev/vend id + * pciFindNext() - Find another PCI device by dev/vend id + * pciReadLong() - Read a 32 bit value from a device's cfg space + * pciReadWord() - Read a 16 bit value from a device's cfg space + * pciReadByte() - Read an 8 bit value from a device's cfg space + * pciWriteLong() - Write a 32 bit value to a device's cfg space + * pciWriteWord() - Write a 16 bit value to a device's cfg space + * pciWriteByte() - Write an 8 bit value to a device's cfg space + * pciSetBitsLong() - Write a 32 bit value against a mask + * pciSetBitsByte() - Write an 8 bit value against a mask + * pciLongFunc() - Return pointer to the requested low level + * function + * pciTag() - Return tag for a given PCI bus, device, & + * function + * pciBusAddrToHostAddr() - Convert a PCI address to a host address + * pciHostAddrToBusAddr() - Convert a host address to a PCI address + * pciGetBaseSize() - Returns the number of bits in a PCI base + * addr mapping + * xf86MapPciMem() - Like xf86MapVidMem() except function expects + * a PCI address and a PCITAG that identifies + * a PCI device + * xf86ReadPciBIOS() - Like xf86ReadBIOS() but can handle PCI/host + * address translation and BIOS decode enabling + * xf86scanpci() - Return info about all PCI devices + * xf86GetPciDomain() - Return domain number from a PCITAG + * xf86MapDomainMemory() - Like xf86MapPciMem() but can handle + * domain/host address translation + * xf86MapDomainIO() - Maps PCI I/O spaces + * xf86ReadDomainMemory() - Like xf86ReadPciBIOS() but can handle + * domain/host address translation + * + * The actual PCI backend driver is selected by the pciInit() function + * (see below) using either compile time definitions, run-time checks, + * or both. + * + * Certain generic functions are provided that make the implementation + * of certain well behaved platforms (e.g. those supporting PCI config + * mechanism 1 or some thing close to it) very easy. + * + * Less well behaved platforms/OS's can roll their own functions. + * + * To add support for another platform/OS, add a call to fooPciInit() within + * pciInit() below under the correct compile time definition or run-time + * conditional. + * + * The fooPciInit() procedure must do three things: + * 1) Initialize the pciBusTable[] for all primary PCI buses including + * the per domain PCI access functions (readLong, writeLong, + * addrBusToHost, and addrHostToBus). + * + * 2) Add entries to pciBusTable[] for configured secondary buses. This + * step may be skipped if a platform is using the generic findFirst/ + * findNext functions because these procedures will automatically + * discover and add secondary buses dynamically. + * + * 3) Overide default settings for global PCI access functions if + * required. These include pciFindFirstFP, pciFindNextFP, + * Of course, if you choose not to use one of the generic + * functions, you will need to provide a platform specifc replacement. + * + * Gary Barton + * Concurrent Computer Corporation + * garyb@gate.net + * + */ + +/* + * 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 software is derived from the original XFree86 PCI code + * which includes the following copyright notices as well: + * + * Copyright 1995 by Robin Cutshaw <robin@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 the above listed copyright holder(s) + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. The above listed + * copyright holder(s) make(s) no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM(S) ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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 code is also based heavily on the code in FreeBSD-current, which was + * written by Wolfgang Stanglmeier, and contains the following copyright: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +#include <errno.h> +#include <signal.h> +#include "Xarch.h" +#include "compiler.h" +#include "xf86.h" +#include "xf86Priv.h" +#define XF86_OS_PRIVS +#include "xf86_OSproc.h" +#include "Pci.h" + +#define PCI_MFDEV_SUPPORT 1 /* Include PCI multifunction device support */ +#define PCI_BRIDGE_SUPPORT 1 /* Include support for PCI-to-PCI bridges */ + +#ifdef PC98 +#define outb(port,data) _outb(port,data) +#define outl(port,data) _outl(port,data) +#define inb(port) _inb(port) +#define inl(port) _inl(port) +#endif + +/* + * Global data + */ +static int pciInitialized = 0; + +CARD32 pciDevid; /* Requested device/vendor ID (after mask) */ +CARD32 pciDevidMask; /* Bit mask applied (AND) before comparison */ + /* of real devid's with requested */ + +int pciBusNum; /* Bus Number of current device */ +int pciDevNum; /* Device number of current device */ +int pciFuncNum; /* Function number of current device */ +PCITAG pciDeviceTag; /* Tag for current device */ + +pciBusInfo_t *pciBusInfo[MAX_PCI_BUSES] = { NULL, }; +int pciNumBuses = 0; /* Actual number of PCI buses */ +int pciMaxBusNum = MAX_PCI_BUSES; +static Bool inProbe = FALSE; + +static pciConfigPtr pci_devp[MAX_PCI_DEVICES + 1] = {NULL, }; + +/* + * Platform specific PCI function pointers. + * + * NOTE: A platform/OS specific pci init procedure can override these defaults + * by setting them to the appropriate platform dependent functions. + */ +PCITAG (*pciFindFirstFP)(void) = pciGenFindFirst; +PCITAG (*pciFindNextFP)(void) = pciGenFindNext; + +/* + * pciInit - choose correct platform/OS specific PCI init routine + */ +void +pciInit() +{ + if (pciInitialized) + return; + + pciInitialized = 1; + + /* XXX */ +#if defined(DEBUGPCI) + if (DEBUGPCI >= xf86Verbose) + xf86Verbose = DEBUGPCI; +#endif + + ARCH_PCI_INIT(); +#if defined(ARCH_PCI_OS_INIT) + if (pciNumBuses <= 0) + ARCH_PCI_OS_INIT(); +#endif +} + +PCITAG +pciFindFirst(CARD32 id, CARD32 mask) +{ +#ifdef DEBUGPCI + ErrorF("pciFindFirst(0x%lx, 0x%lx), pciInit = %d\n", id, mask, pciInitialized); +#endif + pciInit(); + + pciDevid = id & mask; + pciDevidMask = mask; + + return((*pciFindFirstFP)()); +} + +PCITAG +pciFindNext(void) +{ +#ifdef DEBUGPCI + ErrorF("pciFindNext(), pciInit = %d\n", pciInitialized); +#endif + pciInit(); + + return((*pciFindNextFP)()); +} + +CARD32 +pciReadLong(PCITAG tag, int offset) +{ + int bus = PCI_BUS_FROM_TAG(tag); + +#ifdef DEBUGPCI + ErrorF("pciReadLong(0x%lx, %d)\n", tag, offset); +#endif + pciInit(); + + if ((bus >= 0) && ((bus < pciNumBuses) || inProbe) && pciBusInfo[bus] && + pciBusInfo[bus]->funcs->pciReadLong) { + CARD32 rv = (*pciBusInfo[bus]->funcs->pciReadLong)(tag, offset); + + PCITRACE(1, ("pciReadLong: tag=0x%x [b=%d,d=%d,f=%d] returns 0x%08x\n", + tag, bus, PCI_DEV_FROM_TAG(tag), PCI_FUNC_FROM_TAG(tag), rv)); + return(rv); + } + + return(PCI_NOT_FOUND); +} + +CARD16 +pciReadWord(PCITAG tag, int offset) +{ + CARD32 tmp; + int shift = (offset & 3) * 8; + int aligned_offset = offset & ~3; + + if (shift != 0 && shift != 16) + FatalError("pciReadWord: Alignment error: Cannot read 16 bits " + "at offset %d\n", offset); + + tmp = pciReadLong(tag, aligned_offset); + + return((CARD16)((tmp >> shift) & 0xffff)); +} + +CARD8 +pciReadByte(PCITAG tag, int offset) +{ + CARD32 tmp; + int shift = (offset & 3) * 8; + int aligned_offset = offset & ~3; + + tmp = pciReadLong(tag, aligned_offset); + + return((CARD8)((tmp >> shift) & 0xff)); +} + +void +pciWriteLong(PCITAG tag, int offset, CARD32 val) +{ + int bus = PCI_BUS_FROM_TAG(tag); + + pciInit(); + + if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] && + pciBusInfo[bus]->funcs->pciWriteLong) + (*pciBusInfo[bus]->funcs->pciWriteLong)(tag, offset, val); +} + +void +pciWriteWord(PCITAG tag, int offset, CARD16 val) +{ + CARD32 tmp; + int aligned_offset = offset & ~3; + int shift = (offset & 3) * 8; + + if (shift != 0 && shift != 16) + FatalError("pciWriteWord: Alignment Error: Cannot read 16 bits " + "from offset %d\n", offset); + + tmp = pciReadLong(tag, aligned_offset); + + tmp &= ~(0xffffL << shift); + tmp |= (((CARD32)val) << shift); + + pciWriteLong(tag, aligned_offset, tmp); +} + +void +pciWriteByte(PCITAG tag, int offset, CARD8 val) +{ + CARD32 tmp; + int aligned_offset = offset & ~3; + int shift = (offset & 3) *8 ; + + tmp = pciReadLong(tag, aligned_offset); + + tmp &= ~(0xffL << shift); + tmp |= (((CARD32)val) << shift); + + pciWriteLong(tag, aligned_offset, tmp); +} + +void +pciSetBitsLong(PCITAG tag, int offset, CARD32 mask, CARD32 val) +{ + int bus = PCI_BUS_FROM_TAG(tag); + +#ifdef DEBUGPCI + ErrorF("pciReadLong(0x%lx, %d)\n", tag, offset); +#endif + pciInit(); + + if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] && + pciBusInfo[bus]->funcs->pciReadLong) { + (*pciBusInfo[bus]->funcs->pciSetBitsLong)(tag, offset, mask, val); + } +} + +void +pciSetBitsByte(PCITAG tag, int offset, CARD8 mask, CARD8 val) +{ + CARD32 tmp_mask, tmp_val; + int aligned_offset = offset & ~3; + int shift = (offset & 3) *8 ; + + tmp_mask = mask << shift; + tmp_val = val << shift; + pciSetBitsLong(tag, aligned_offset, tmp_mask, tmp_val); +} + +pointer +pciLongFunc(PCITAG tag, pciFunc func) +{ + int bus = PCI_BUS_FROM_TAG(tag); + + pciInit(); + + if ((bus < 0) || (bus > pciNumBuses) || !pciBusInfo[bus] || + !pciBusInfo[bus]->funcs->pciReadLong) return NULL; + + switch (func) { + case WRITE: + return (void *)pciBusInfo[bus]->funcs->pciWriteLong; + case READ: + return (void *)pciBusInfo[bus]->funcs->pciReadLong; + case SET_BITS: + return (void *)pciBusInfo[bus]->funcs->pciSetBitsLong; + } + return NULL; +} + +ADDRESS +pciBusAddrToHostAddr(PCITAG tag, PciAddrType type, ADDRESS addr) +{ + int bus = PCI_BUS_FROM_TAG(tag); + + pciInit(); + + if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] && + pciBusInfo[bus]->funcs->pciAddrBusToHost) + return (*pciBusInfo[bus]->funcs->pciAddrBusToHost)(tag, type, addr); + else + return(addr); +} + +ADDRESS +pciHostAddrToBusAddr(PCITAG tag, PciAddrType type, ADDRESS addr) +{ + int bus = PCI_BUS_FROM_TAG(tag); + + pciInit(); + + if ((bus >= 0) && (bus < pciNumBuses) && pciBusInfo[bus] && + pciBusInfo[bus]->funcs->pciAddrHostToBus) + return (*pciBusInfo[bus]->funcs->pciAddrHostToBus)(tag, type, addr); + else + return(addr); +} + +/* + * pciGetBaseSize() returns the size of a PCI base address mapping in bits. + * The index identifies the base register: 0-5 are the six standard registers, + * and 6 is the ROM base register. If destructive is TRUE, it will write + * to the base address register to get an accurate result. Otherwise it + * makes a conservative guess based on the alignment of the already allocated + * address. If the result is accurate (ie, not an over-estimate), this is + * indicated by setting *min to TRUE (when min is non-NULL). This currently + * only happens when the destructive flag is set, but in future it may be + * possible to get the information from the OS when supported. + */ + +int +pciGetBaseSize(PCITAG tag, int index, Bool destructive, Bool *min) +{ + int offset; + CARD32 addr1; + CARD32 addr2; + CARD32 mask1; + CARD32 mask2; + int bits = 0; + + /* + * Eventually a function for this should be added to pciBusFuncs_t, but for + * now we'll just use a simple method based on the alignment of the already + * allocated address. + */ + + /* + * silently ignore bogus index values. Valid values are 0-6. 0-5 are + * the 6 base address registers, and 6 is the ROM base address register. + */ + if (index < 0 || index > 6) + return 0; + + pciInit(); + + if (xf86GetPciSizeFromOS(tag, index, &bits)) { + if (min) + *min = TRUE; + return bits; + } + + if (min) + *min = destructive; + + /* Get the PCI offset */ + if (index == 6) + offset = PCI_MAP_ROM_REG; + else + offset = PCI_MAP_REG_START + (index << 2); + + addr1 = pciReadLong(tag, offset); + /* + * Check if this is the second part of a 64 bit address. + * XXX need to check how endianness affects 64 bit addresses. + */ + if (index > 0 && index < 6) { + addr2 = pciReadLong(tag, offset - 4); + if (PCI_MAP_IS_MEM(addr2) && PCI_MAP_IS64BITMEM(addr2)) + return 0; + } + + if (destructive) { + pciWriteLong(tag, offset, 0xffffffff); + mask1 = pciReadLong(tag, offset); + pciWriteLong(tag, offset, addr1); + } else { + mask1 = addr1; + } + + /* Check if this is the first part of a 64 bit address. */ + if (index < 5 && PCI_MAP_IS_MEM(mask1) && PCI_MAP_IS64BITMEM(mask1)) { + if (PCIGETMEMORY(mask1) == 0) { + addr2 = pciReadLong(tag, offset + 4); + if (destructive) { + pciWriteLong(tag, offset + 4, 0xffffffff); + mask2 = pciReadLong(tag, offset + 4); + pciWriteLong(tag, offset + 4, addr2); + } else { + mask2 = addr2; + } + if (mask2 == 0) + return 0; + bits = 32; + while ((mask2 & 1) == 0) { + bits++; + mask2 >>= 1; + } + if (bits > 32) + return bits; + } + } + if (index < 6) + if (PCI_MAP_IS_MEM(mask1)) + mask1 = PCIGETMEMORY(mask1); + else + mask1 = PCIGETIO(mask1); + else + mask1 = PCIGETROM(mask1); + if (mask1 == 0) + return 0; + bits = 0; + while ((mask1 & 1) == 0) { + bits++; + mask1 >>= 1; + } + /* I/O maps can be no larger than 8 bits */ + +#if defined(Lynx) && defined(__powerpc__) + if (PCI_MAP_IS_IO(addr1) && bits > 8) +#else + if ((index < 6) && PCI_MAP_IS_IO(addr1) && bits > 8) +#endif + bits = 8; + /* ROM maps can be no larger than 24 bits */ + if (index == 6 && bits > 24) + bits = 24; + return bits; +} + +PCITAG +pciTag(int busnum, int devnum, int funcnum) +{ + return(PCI_MAKE_TAG(busnum,devnum,funcnum)); +} + +Bool +pciMfDev(int busnum, int devnum) +{ + PCITAG tag0, tag1; + unsigned long id0, id1, val; + + /* Detect a multi-function device that complies to the PCI 2.0 spec */ + + tag0 = PCI_MAKE_TAG(busnum, devnum, 0); + id0 = pciReadLong(tag0, PCI_ID_REG); + if (id0 == 0xffffffff) + return FALSE; + + val = pciReadLong(tag0, PCI_HEADER_MISC) & 0x00ff0000; + if ((val != 0x00ff0000) && (val & PCI_HEADER_MULTIFUNCTION)) + return TRUE; + + /* + * Now, to find non-compliant devices... + * If there is a valid ID for function 1 and the ID for func 0 and 1 + * are different, or the base0 values of func 0 and 1 are differend, + * then assume there is a multi-function device. + */ + tag1 = PCI_MAKE_TAG(busnum, devnum, 1); + id1 = pciReadLong(tag1, PCI_ID_REG); + if (id1 == 0xffffffff || id1 == 0x00000000) + return FALSE; + + if ((id0 != id1) || + (pciReadLong(tag0, PCI_MAP_REG_START) != + pciReadLong(tag1, PCI_MAP_REG_START))) + return TRUE; + + return FALSE; +} + +/* + * Generic find/read/write functions + */ +PCITAG +pciGenFindNext(void) +{ + CARD32 devid, tmp; + int sec_bus, pri_bus; + static int previousBus = 0; + Bool speculativeProbe = FALSE; + unsigned char base_class, sub_class; + +#ifdef DEBUGPCI + ErrorF("pciGenFindNext\n"); +#endif + + for (;;) { + +#ifdef DEBUGPCI + ErrorF("pciGenFindNext: pciBusNum %d\n", pciBusNum); +#endif + if (pciBusNum == -1) { + /* + * Start at top of the order + */ + if (pciNumBuses <= 0) + return(PCI_NOT_FOUND); + + /* Skip ahead to the first bus defined by pciInit() */ + for (pciBusNum = 0; !pciBusInfo[pciBusNum]; ++pciBusNum); + pciFuncNum = 0; + pciDevNum = 0; + previousBus = pciBusNum; /* make sure previousBus exists */ + } else { +#ifdef PCI_MFDEV_SUPPORT +#ifdef DEBUGPCI + ErrorF("pciGenFindNext: pciFuncNum %d\n", pciFuncNum); +#endif + /* + * Somewhere in middle of order. Determine who's + * next up + */ + if (pciFuncNum == 0) { + /* + * Is current dev a multifunction device? + */ + if (!speculativeProbe && 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 + pciDevNum ++; +#endif + if (pciDevNum >= 32 || + !pciBusInfo[pciBusNum] || + pciDevNum >= pciBusInfo[pciBusNum]->numDevices) { +#ifdef DEBUGPCI + ErrorF("pciGenFindNext: next bus\n"); +#endif + /* + * No more devices for this bus. Next bus please + */ + if (speculativeProbe) { + xfree(pciBusInfo[pciBusNum]); + pciBusInfo[pciBusNum] = NULL; + speculativeProbe = FALSE; + } + + if (++pciBusNum >= pciMaxBusNum) { +#ifdef DEBUGPCI + ErrorF("pciGenFindNext: out of buses\n"); +#endif + /* No more buses. All done for now */ + return(PCI_NOT_FOUND); + } + + pciDevNum = 0; + } + } + +#ifdef DEBUGPCI + ErrorF("pciGenFindNext: pciBusInfo[%d] = 0x%lx\n", pciBusNum, pciBusInfo[pciBusNum]); +#endif + if (!pciBusInfo[pciBusNum]) { + pciBusInfo[pciBusNum] = xnfalloc(sizeof(pciBusInfo_t)); + *pciBusInfo[pciBusNum] = *pciBusInfo[previousBus]; + + speculativeProbe = TRUE; + } + + /* + * At this point, pciBusNum, pciDevNum, and pciFuncNum have been + * advanced to the next device. Compute the tag, and read the + * device/vendor ID field. + */ +#ifdef DEBUGPCI + ErrorF("pciGenFindNext: [%d, %d, %d]\n", pciBusNum, pciDevNum, pciFuncNum); +#endif + pciDeviceTag = PCI_MAKE_TAG(pciBusNum, pciDevNum, pciFuncNum); + inProbe = TRUE; + devid = pciReadLong(pciDeviceTag, 0); + inProbe = FALSE; +#ifdef DEBUGPCI + ErrorF("pciGenFindNext: pciDeviceTag = 0x%lx, devid = 0x%lx\n", pciDeviceTag, devid); +#endif + if ((CARD16)(devid + 1U) <= (CARD16)1UL) + continue; /* Nobody home. Next device please */ + + if (pciNumBuses <= pciBusNum) + pciNumBuses = pciBusNum + 1; + + speculativeProbe = FALSE; + previousBus = pciBusNum; + + /* + * 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). + */ +#ifdef PCI_BRIDGE_SUPPORT + tmp = pciReadLong(pciDeviceTag, PCI_CLASS_REG); + base_class = PCI_CLASS_EXTRACT(tmp); + sub_class = PCI_SUBCLASS_EXTRACT(tmp); + if ((base_class == PCI_CLASS_BRIDGE) && + ((sub_class == PCI_SUBCLASS_BRIDGE_PCI) || + (sub_class == PCI_SUBCLASS_BRIDGE_CARDBUS))) { + tmp = pciReadLong(pciDeviceTag, PCI_PCI_BRIDGE_BUS_REG); + sec_bus = PCI_SECONDARY_BUS_EXTRACT(tmp, pciDeviceTag); + pri_bus = PCI_PRIMARY_BUS_EXTRACT(tmp, pciDeviceTag); +#ifdef DEBUGPCI + ErrorF("pciGenFindNext: pri_bus %d sec_bus %d\n", + pri_bus, sec_bus); +#endif + if (pciBusNum != pri_bus) { + /* Some bridges do not implement the primary bus register */ + if ((PCI_BUS_NO_DOMAIN(pri_bus) != 0) || + (sub_class != PCI_SUBCLASS_BRIDGE_CARDBUS)) + xf86Msg(X_WARNING, + "pciGenFindNext: primary bus mismatch on PCI" + " bridge 0x%08x (0x%02x, 0x%02x)\n", + pciDeviceTag, pciBusNum, pri_bus); + pri_bus = pciBusNum; + } + if ((pri_bus < sec_bus) && (sec_bus < pciMaxBusNum) && + pciBusInfo[pri_bus]) { + /* + * Found a secondary PCI bus + */ + if (!pciBusInfo[sec_bus]) { + pciBusInfo[sec_bus] = xnfalloc(sizeof(pciBusInfo_t)); + + /* 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_bus) + pciNumBuses = sec_bus + 1; + } + } +#endif + + /* + * Does this device match the requested devid after + * applying mask? + */ +#ifdef DEBUGPCI + ErrorF("pciGenFindNext: pciDevidMask = 0x%lx, pciDevid = 0x%lx\n", pciDevidMask, pciDevid); +#endif + if ((devid & pciDevidMask) == pciDevid) + /* Yes - Return it. Otherwise, next device */ + return(pciDeviceTag); /* got a match */ + + } /* for */ + /*NOTREACHED*/ +} + +PCITAG +pciGenFindFirst(void) +{ + /* Reset PCI bus number to start from top */ + pciBusNum = -1; + + return pciGenFindNext(); +} + +#if defined (__powerpc__) +static int buserr_detected; + +static +void buserr(int sig) +{ + buserr_detected = 1; +} +#endif + +CARD32 +pciCfgMech1Read(PCITAG tag, int offset) +{ + unsigned long rv = 0xffffffff; +#ifdef DEBUGPCI + ErrorF("pciCfgMech1Read(tag=%08x,offset=%08x)\n", tag, offset); +#endif + +#if defined(__powerpc__) + signal(SIGBUS, buserr); + buserr_detected = 0; +#endif + + outl(0xCF8, PCI_EN | tag | (offset & 0xfc)); + rv = inl(0xCFC); + +#if defined(__powerpc__) + signal(SIGBUS, SIG_DFL); + if (buserr_detected) + { +#ifdef DEBUGPCI + ErrorF("pciCfgMech1Read() BUS ERROR\n"); +#endif + return(0xffffffff); + } + else +#endif + return(rv); +} + +void +pciCfgMech1Write(PCITAG tag, int offset, CARD32 val) +{ +#ifdef DEBUGPCI + ErrorF("pciCfgMech1Write(tag=%08x,offset=%08x,val=%08x)\n", + tag, offset,val); +#endif + +#if defined(__powerpc__) + signal(SIGBUS, SIG_IGN); +#endif + + outl(0xCF8, PCI_EN | tag | (offset & 0xfc)); +#if defined(Lynx) && defined(__powerpc__) + outb(0x80, 0x00); /* without this the next access fails + * on my Powerstack system when we use + * assembler inlines for outl */ +#endif + outl(0xCFC, val); + +#if defined(__powerpc__) + signal(SIGBUS, SIG_DFL); +#endif +} + +void +pciCfgMech1SetBits(PCITAG tag, int offset, CARD32 mask, CARD32 val) +{ + unsigned long rv = 0xffffffff; + +#if defined(__powerpc__) + signal(SIGBUS, buserr); +#endif + + outl(0xCF8, PCI_EN | tag | (offset & 0xfc)); + rv = inl(0xCFC); + rv = (rv & ~mask) | val; + outl(0xCFC, rv); + +#if defined(__powerpc__) + signal(SIGBUS, SIG_DFL); +#endif +} + +CARD32 +pciByteSwap(CARD32 u) +{ +#if X_BYTE_ORDER == X_BIG_ENDIAN +# if defined(__powerpc__) && defined(PowerMAX_OS) + CARD32 tmp; + + __inst_stwbrx(u, &tmp, 0); + + return(tmp); + +# else /* !PowerMAX_OS */ + + return lswapl(u); + +# endif /* !PowerMAX_OS */ + +#else /* !BIG_ENDIAN */ + + return(u); + +#endif +} + +ADDRESS +pciAddrNOOP(PCITAG tag, PciAddrType type, ADDRESS addr) +{ + return(addr); +} + +pciConfigPtr * +xf86scanpci(int flags) +{ + pciConfigPtr devp; + pciBusInfo_t *busp; + int idx = 0, i; + PCITAG tag; + + if (pci_devp[0]) + return pci_devp; + + pciInit(); + +#ifdef XF86SCANPCI_WRAPPER + XF86SCANPCI_WRAPPER(SCANPCI_INIT); +#endif + + tag = pciFindFirst(0,0); /* 0 mask means match any valid device */ + /* Check if no devices, return now */ + if (tag == PCI_NOT_FOUND) { +#ifdef XF86SCANPCI_WRAPPER + XF86SCANPCI_WRAPPER(SCANPCI_TERM); +#endif + return NULL; + } + +#ifdef DEBUGPCI + ErrorF("xf86scanpci: tag = 0x%lx\n", tag); +#endif +#ifndef OLD_FORMAT + xf86MsgVerb(X_INFO, 2, "PCI: PCI scan (all values are in hex)\n"); +#endif + + while (idx < MAX_PCI_DEVICES && tag != PCI_NOT_FOUND) { + devp = xcalloc(1, sizeof(pciDevice)); + if (!devp) { + xf86Msg(X_ERROR, + "xf86scanpci: Out of memory after %d devices!!\n", idx); + return (pciConfigPtr *)NULL; + } + + /* Identify pci device by bus, dev, func, and tag */ + devp->tag = tag; + devp->busnum = PCI_BUS_FROM_TAG(tag); + devp->devnum = PCI_DEV_FROM_TAG(tag); + devp->funcnum = PCI_FUNC_FROM_TAG(tag); + + /* Read config space for this device */ + for (i = 0; i < 17; i++) /* PCI hdr plus 1st dev spec dword */ + devp->cfgspc.dwords[i] = pciReadLong(tag, i * sizeof(CARD32)); + +#ifdef ARCH_PCI_HOST_BRIDGE + if ((devp->pci_base_class == PCI_CLASS_BRIDGE) && + (devp->pci_sub_class == PCI_SUBCLASS_BRIDGE_HOST)) + ARCH_PCI_HOST_BRIDGE(devp); +#endif + + /* Some broken devices don't implement this field... */ + if (devp->pci_header_type == 0xff) + devp->pci_header_type = 0; + + switch (devp->pci_header_type & 0x7f) { + case 0: + /* Get base address sizes for type 0 headers */ + for (i = 0; i < 7; i++) + devp->basesize[i] = + pciGetBaseSize(tag, i, FALSE, &devp->minBasesize); + break; + + case 1: + case 2: + /* Allow master aborts to complete normally on secondary buses */ + if (!(devp->pci_bridge_control & PCI_PCI_BRIDGE_MASTER_ABORT_EN)) + break; + pciWriteByte(tag, PCI_PCI_BRIDGE_CONTROL_REG, + devp->pci_bridge_control & ~PCI_PCI_BRIDGE_MASTER_ABORT_EN); + break; + + default: + break; + } + +#ifdef OLD_FORMAT + xf86MsgVerb(X_INFO, 2, "PCI: BusID 0x%.2x,0x%02x,0x%1x " + "ID 0x%04x,0x%04x Rev 0x%02x Class 0x%02x,0x%02x\n", + devp->busnum, devp->devnum, devp->funcnum, + devp->pci_vendor, devp->pci_device, devp->pci_rev_id, + devp->pci_base_class, devp->pci_sub_class); +#else + xf86MsgVerb(X_INFO, 2, "PCI: %.2x:%02x:%1x: chip %04x,%04x" + " card %04x,%04x rev %02x class %02x,%02x,%02x hdr %02x\n", + devp->busnum, devp->devnum, devp->funcnum, + devp->pci_vendor, devp->pci_device, + devp->pci_subsys_vendor, devp->pci_subsys_card, + devp->pci_rev_id, devp->pci_base_class, + devp->pci_sub_class, devp->pci_prog_if, + devp->pci_header_type); +#endif + + pci_devp[idx++] = devp; + tag = pciFindNext(); + +#ifdef DEBUGPCI + ErrorF("xf86scanpci: tag = pciFindNext = 0x%lx\n", tag); +#endif + } + + /* Restore modified data (in reverse order), and link buses */ + while (--idx >= 0) { + devp = pci_devp[idx]; + switch (devp->pci_header_type & 0x7f) { + case 0: + if ((devp->pci_base_class != PCI_CLASS_BRIDGE) || + (devp->pci_sub_class != PCI_SUBCLASS_BRIDGE_HOST)) + break; + pciBusInfo[devp->busnum]->bridge = devp; + pciBusInfo[devp->busnum]->primary_bus = devp->busnum; + break; + + case 1: + case 2: + i = PCI_SECONDARY_BUS_EXTRACT(devp->pci_pp_bus_register, devp->tag); + if (i > devp->busnum) { + if (pciBusInfo[i]) { + pciBusInfo[i]->bridge = devp; + /* + * The back link needs to be set here, and is unlikely to + * change. + */ + devp->businfo = pciBusInfo[i]; + } +#ifdef ARCH_PCI_PCI_BRIDGE + ARCH_PCI_PCI_BRIDGE(devp); +#endif + } + if (!(devp->pci_bridge_control & PCI_PCI_BRIDGE_MASTER_ABORT_EN)) + break; + pciWriteByte(devp->tag, PCI_PCI_BRIDGE_CONTROL_REG, + devp->pci_bridge_control); + break; + + default: + break; + } + } + +#ifdef XF86SCANPCI_WRAPPER + XF86SCANPCI_WRAPPER(SCANPCI_TERM); +#endif + + /* + * Lastly, link bridges to their secondary bus, after the architecture has + * had a chance to modify these assignments. + */ + for (idx = 0; idx < pciNumBuses; idx++) { + if (!(busp = pciBusInfo[idx]) || !(devp = busp->bridge)) + continue; + devp->businfo = busp; + } + +#ifndef OLD_FORMAT + xf86MsgVerb(X_INFO, 2, "PCI: End of PCI scan\n"); +#endif + + return pci_devp; +} + +CARD32 +pciCheckForBrokenBase(PCITAG Tag,int basereg) +{ + pciWriteLong(Tag, PCI_MAP_REG_START + (basereg << 2), 0xffffffff); + return pciReadLong(Tag, PCI_MAP_REG_START + (basereg << 2)); +} + +#if defined(INCLUDE_XF86_MAP_PCI_MEM) + +pointer +xf86MapPciMem(int ScreenNum, int Flags, PCITAG Tag, ADDRESS Base, + unsigned long Size) +{ + ADDRESS hostbase = pciBusAddrToHostAddr(Tag, PCI_MEM,Base); + pointer base; + CARD32 save = 0; + + /* + * If there are possible read side-effects, disable memory while + * doing the mapping. + */ + if (Flags & VIDMEM_READSIDEEFFECT) { + save = pciReadLong(Tag, PCI_CMD_STAT_REG); + pciWriteLong(Tag, PCI_CMD_STAT_REG, + save & ~PCI_CMD_MEM_ENABLE); + } + base = xf86MapDomainMemory(ScreenNum, Flags, Tag, hostbase, Size); + if (!base) { + FatalError("xf86MapPciMem: Could not mmap PCI memory " + "[base=0x%x,hostbase=0x%x,size=%x] (%s)\n", + Base, hostbase, Size, strerror(errno)); + } + /* + * If read side-effects, do whatever might be needed to prevent + * unintended reads, then restore PCI_CMD_STAT_REG. + */ + if (Flags & VIDMEM_READSIDEEFFECT) { + xf86MapReadSideEffects(ScreenNum, Flags, base, Size); + pciWriteLong(Tag, PCI_CMD_STAT_REG, save); + } + return((pointer)base); +} + +static int +handlePciBIOS(PCITAG Tag, int basereg, + int (*func)(PCITAG, CARD8*, ADDRESS, pointer), + pointer args) +{ + CARD32 romsave = 0; + int i; + romBaseSource b_reg; + ADDRESS hostbase; + CARD8 tmp[64]; + int ret = 0; + + romsave = pciReadLong(Tag, PCI_MAP_ROM_REG); + + for (i = ROM_BASE_PRESET; i <= ROM_BASE_FIND; i++) { + memType savebase = 0, newbase, romaddr; + + if (i == ROM_BASE_PRESET) { + /* Does the driver have a preference? */ + if (basereg > ROM_BASE_PRESET && basereg <= ROM_BASE_FIND) + b_reg = basereg; + else + b_reg = ++i; + } else + b_reg = i; + + if (!(newbase = getValidBIOSBase(Tag, b_reg))) + continue; /* no valid address found */ + + romaddr = PCIGETROM(newbase); + + /* if we use a mem base save it and move it out of the way */ + if (b_reg >= 0 && b_reg <= 5) { + savebase = pciReadLong(Tag, PCI_MAP_REG_START+(b_reg<<2)); + xf86MsgVerb(X_INFO,5,"xf86ReadPciBios: modifying membase[%i]" + " for device %i:%i:%i\n", basereg, + PCI_BUS_FROM_TAG(Tag), PCI_DEV_FROM_TAG(Tag), + PCI_FUNC_FROM_TAG(Tag)); + pciWriteLong(Tag, PCI_MAP_REG_START + (b_reg << 2), + (CARD32)~0); + } + /* Set ROM base address and enable ROM address decoding */ + pciWriteLong(Tag, PCI_MAP_ROM_REG, romaddr + | PCI_MAP_ROM_DECODE_ENABLE); + + hostbase = pciBusAddrToHostAddr(Tag, PCI_MEM, PCIGETROM(romaddr)); + + if ((xf86ReadDomainMemory(Tag, hostbase, sizeof(tmp), tmp) != + sizeof(tmp)) || + (tmp[0] != 0x55) || (tmp[1] != 0xaa) || !tmp[2] ) { + /* Restore the base register if it was changed. */ + if (savebase) pciWriteLong(Tag, PCI_MAP_REG_START + (b_reg << 2), + (CARD32) savebase); + + /* No BIOS found: try another address */ + continue; + } + + ret = (*func)(Tag, tmp, hostbase, args); + + /* Restore the base register if it was changed. */ + if (savebase) pciWriteLong(Tag, PCI_MAP_REG_START + (b_reg << 2), + (CARD32) savebase); + /* Restore ROM address decoding */ + pciWriteLong(Tag, PCI_MAP_ROM_REG, romsave); + + return ret; + } + /* Restore ROM address decoding */ + pciWriteLong(Tag, PCI_MAP_ROM_REG, romsave); + return 0; +} + +typedef struct { + unsigned long Offset; + int Len; + unsigned char *Buf; + PciBiosType BiosType; +} readBios, *readBiosPtr; + +static int +readPciBios(PCITAG Tag, CARD8* tmp, ADDRESS hostbase, pointer args) +{ + unsigned int image_length = 0; + readBiosPtr rd = args; + int ret; + + /* We found a PCI BIOS Image. Now we look for the correct type */ + while ((tmp[0] == 0x55) && (tmp[1] == 0xAA)) { + unsigned short data_off = tmp[0x18] | (tmp[0x19] << 8); + unsigned char data[0x18]; + unsigned char type; + + if ((xf86ReadDomainMemory(Tag, hostbase + data_off, sizeof(data), data) + != sizeof(data)) || + (data[0] != 'P') || + (data[1] != 'C') || + (data[2] != 'I') || + (data[3] != 'R')) + break; + type = data[0x14]; +#ifdef PRINT_PCI + ErrorF("data segment in BIOS: 0x%x, type: 0x%x\n", data_off, type); +#endif + if (type != rd->BiosType) { /* not correct image: find next one */ + unsigned char indicator = data[0x15]; + unsigned int i_length; + if (indicator & 0x80) /* last image */ + break; + i_length = (data[0x10] | (data[0x11] << 8)) << 9; +#ifdef PRINT_PCI + ErrorF("data image length: 0x%x, ind: 0x%x\n", + image_length, indicator); +#endif + hostbase += i_length; + if (xf86ReadDomainMemory(Tag, hostbase, sizeof(tmp), tmp) + != sizeof(tmp)) + break; + continue; + } + /* OK, we have a PCI BIOS Image of the correct type */ + + if (rd->BiosType == PCI_BIOS_PC) + image_length = tmp[2] << 9; + else + image_length = (data[0x10] | (data[0x11] << 8)) << 9; +#ifdef PRINT_PCI + ErrorF("BIOS length: 0x%x\n", image_length); +#endif + break; + } + + ret = 0; + if (image_length) { + + /* + * if no length is given return the full lenght, + * Offset 0. Beware: Area pointed to by Buf must + * be large enough! + */ + if (rd->Len == 0) { + rd->Len = image_length; + rd->Offset = 0; + } + if ((rd->Offset) > (image_length)) { + xf86Msg(X_WARNING,"xf86ReadPciBios: requesting data past " + "end of BIOS %i > %i\n",(rd->Offset) , (image_length)); + } else { + if ((rd->Offset + rd->Len) > (image_length)) { + rd->Len = (image_length) - rd->Offset; + xf86MsgVerb(X_INFO,3,"Truncating PCI BIOS Length to %i\n",rd->Len); + } + } + + /* Read BIOS */ + ret = xf86ReadDomainMemory(Tag, hostbase + rd->Offset, rd->Len, rd->Buf); + } + + return ret; +} + +static int +getPciBIOSTypes(PCITAG Tag, CARD8* tmp, ADDRESS hostbase, pointer arg) +{ + int n = 0; + PciBiosType *Buf = arg; + + /* We found a PCI BIOS Image. Now we collect the types type */ + do { + unsigned short data_off = tmp[0x18] | (tmp[0x19] << 8); + unsigned char data[16]; + unsigned int i_length; + + if ((xf86ReadDomainMemory(Tag, hostbase + data_off, sizeof(data), data) + != sizeof(data)) || + (data[0] != 'P') || + (data[1] != 'C') || + (data[2] != 'I') || + (data[3] != 'R')) + break; + + if (data[0x14] >= PCI_BIOS_OTHER) + *Buf++ = PCI_BIOS_OTHER; + else + *Buf++ = data[0x14]; + + n++; + if (data[0x15] & 0x80) /* last image */ + break; +#ifdef PRINT_PCI + ErrorF("data segment in BIOS: 0x%x, type: 0x%x\n", data_off, type); +#endif + i_length = (data[0x10] | (data[0x11] << 8)) << 9; +#ifdef PRINT_PCI + ErrorF("data image length: 0x%x, ind: 0x%x\n", + image_length, indicator); +#endif + hostbase += i_length; + if (xf86ReadDomainMemory(Tag, hostbase, sizeof(tmp), tmp) + != sizeof(tmp)) + break; + continue; + } while ((tmp[0] == 0x55) && (tmp[1] == 0xAA)); + return n; +} + +typedef CARD32 (*ReadProcPtr)(PCITAG, int); +typedef void (*WriteProcPtr)(PCITAG, int, CARD32); + +static int +HandlePciBios(PCITAG Tag, int basereg, + int (*func)(PCITAG, CARD8*, ADDRESS, pointer), + pointer ptr) +{ + int n, num; + CARD32 Acc1, Acc2; + PCITAG *pTag; + int i; + + n = handlePciBIOS(Tag,basereg,func,ptr); + if (n) + return n; + + num = pciTestMultiDeviceCard(PCI_BUS_FROM_TAG(Tag), + PCI_DEV_FROM_TAG(Tag), + PCI_FUNC_FROM_TAG(Tag),&pTag); + + if (!num) return 0; + +#define PCI_ENA (PCI_CMD_MEM_ENABLE | PCI_CMD_IO_ENABLE) + Acc1 = ((ReadProcPtr)(pciLongFunc(Tag,READ)))(Tag,PCI_CMD_STAT_REG); + ((WriteProcPtr)(pciLongFunc(Tag,WRITE)))(Tag, + PCI_CMD_STAT_REG,(Acc1 & ~PCI_ENA)); + + for (i = 0; i < num; i++) { + Acc2 = ((ReadProcPtr)(pciLongFunc(pTag[i],READ)))(pTag[i],PCI_CMD_STAT_REG); + ((WriteProcPtr)(pciLongFunc(pTag[i],WRITE)))(pTag[i], + PCI_CMD_STAT_REG,(Acc2 | PCI_ENA)); + + n = handlePciBIOS(pTag[i],0,func,ptr); + + ((WriteProcPtr)(pciLongFunc(pTag[i],WRITE)))(pTag[i],PCI_CMD_STAT_REG,Acc2); + if (n) + break; + } + ((WriteProcPtr)(pciLongFunc(Tag,WRITE)))(Tag,PCI_CMD_STAT_REG,Acc1); + return n; +} + +int +xf86ReadPciBIOS(unsigned long Offset, PCITAG Tag, int basereg, + unsigned char *Buf, int Len) +{ + return xf86ReadPciBIOSByType(Offset, Tag, basereg, Buf, Len, PCI_BIOS_PC); +} + +int +xf86ReadPciBIOSByType(unsigned long Offset, PCITAG Tag, int basereg, + unsigned char *Buf, int Len, PciBiosType Type) +{ + + readBios rb; + rb.Offset = Offset; + rb.Len = Len; + rb.Buf = Buf; + rb.BiosType = Type; + + return HandlePciBios(Tag, basereg, readPciBios, &rb); +} + +int +xf86GetAvailablePciBIOSTypes(PCITAG Tag, int basereg, PciBiosType *Buf) +{ + return HandlePciBios(Tag, basereg, getPciBIOSTypes, (pointer) Buf); +} + +#endif /* INCLUDE_XF86_MAP_PCI_MEM */ + +#ifdef INCLUDE_XF86_NO_DOMAIN + +int +xf86GetPciDomain(PCITAG Tag) +{ + return 0; +} + +pointer +xf86MapDomainMemory(int ScreenNum, int Flags, PCITAG Tag, + ADDRESS Base, unsigned long Size) +{ + return xf86MapVidMem(ScreenNum, Flags, Base, Size); +} + +IOADDRESS +xf86MapDomainIO(int ScreenNum, int Flags, PCITAG Tag, + IOADDRESS Base, unsigned long Size) +{ + return Base; +} + +int +xf86ReadDomainMemory(PCITAG Tag, ADDRESS Base, int Len, unsigned char *Buf) +{ + int ret, length, rlength; + + /* Read in 64kB chunks */ + ret = 0; + while ((length = Len) > 0) { + if (length > 0x010000) length = 0x010000; + rlength = xf86ReadBIOS(Base, 0, Buf, length); + if (rlength < 0) { + ret = rlength; + break; + } + ret += rlength; + if (rlength < length) break; + Base += rlength; + Buf += rlength; + Len -= rlength; + } + + return ret; +} + +#endif /* INCLUDE_XF86_NO_DOMAIN */ diff --git a/hw/xfree86/os-support/bus/Pci.h b/hw/xfree86/os-support/bus/Pci.h new file mode 100644 index 000000000..8fb421b34 --- /dev/null +++ b/hw/xfree86/os-support/bus/Pci.h @@ -0,0 +1,403 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/Pci.h,v 1.36.2.1 2003/03/21 22:29:59 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 is derived in part from the original xf86_PCI.h that included + * following copyright message: + * + * Copyright 1995 by Robin Cutshaw <robin@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 the above listed copyright holder(s) + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. The above listed + * copyright holder(s) make(s) no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM(S) ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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 has the private Pci definitions. The public ones are imported + * from xf86Pci.h. Drivers should not use this file. + */ +#ifndef _PCI_H +#define _PCI_H 1 + +#include "Xarch.h" +#include "Xfuncproto.h" +#include "xf86Pci.h" +#include "xf86PciInfo.h" + +/* + * Global Definitions + */ +#define MAX_PCI_DEVICES 64 /* Max number of devices accomodated */ + /* by xf86scanpci */ +#if defined(sun) && defined(SVR4) && defined(sparc) +# define MAX_PCI_BUSES 4096 /* Max number of PCI buses */ +#elif defined(__alpha__) && defined (linux) +# define MAX_PCI_DOMAINS 512 +# define PCI_DOM_MASK 0x01fful +# define MAX_PCI_BUSES (MAX_PCI_DOMAINS*256) /* 256 per domain */ +#else +# define MAX_PCI_BUSES 256 /* Max number of PCI buses */ +#endif + +#define DEVID(vendor, device) \ + ((CARD32)((PCI_CHIP_##device << 16) | PCI_VENDOR_##vendor)) + +#ifndef PCI_DOM_MASK +# define PCI_DOM_MASK 0x0ffu +#endif +#define PCI_DOMBUS_MASK (((PCI_DOM_MASK) << 8) | 0x0ffu) + +/* + * "b" contains an optional domain number. + */ +#define PCI_MAKE_TAG(b,d,f) ((((b) & (PCI_DOMBUS_MASK)) << 16) | \ + (((d) & 0x00001fu) << 11) | \ + (((f) & 0x000007u) << 8)) + +#define PCI_MAKE_BUS(d,b) ((((d) & (PCI_DOM_MASK)) << 8) | ((b) & 0xffu)) + +#define PCI_DOM_FROM_TAG(tag) (((tag) >> 24) & (PCI_DOM_MASK)) +#define PCI_BUS_FROM_TAG(tag) (((tag) >> 16) & (PCI_DOMBUS_MASK)) +#define PCI_DEV_FROM_TAG(tag) (((tag) & 0x0000f800u) >> 11) +#define PCI_FUNC_FROM_TAG(tag) (((tag) & 0x00000700u) >> 8) + +#define PCI_DFN_FROM_TAG(tag) (((tag) & 0x0000ff00u) >> 8) +#define PCI_BDEV_FROM_TAG(tag) ((tag) & 0x00fff800u) + +#define PCI_DOM_FROM_BUS(bus) (((bus) >> 8) & (PCI_DOM_MASK)) +#define PCI_BUS_NO_DOMAIN(bus) ((bus) & 0xffu) +#define PCI_TAG_NO_DOMAIN(tag) ((tag) & 0x00ffff00u) + +/* + * Macros for bus numbers found in P2P headers. + */ +#define PCI_PRIMARY_BUS_EXTRACT(x, tag) \ + ((((x) & PCI_PRIMARY_BUS_MASK ) >> 0) | (PCI_DOM_FROM_TAG(tag) << 8)) +#define PCI_SECONDARY_BUS_EXTRACT(x, tag) \ + ((((x) & PCI_SECONDARY_BUS_MASK ) >> 8) | (PCI_DOM_FROM_TAG(tag) << 8)) +#define PCI_SUBORDINATE_BUS_EXTRACT(x, tag) \ + ((((x) & PCI_SUBORDINATE_BUS_MASK) >> 16) | (PCI_DOM_FROM_TAG(tag) << 8)) + +#define PCI_PRIMARY_BUS_INSERT(x, y) \ + (((x) & ~PCI_PRIMARY_BUS_MASK ) | (((y) & 0xffu) << 0)) +#define PCI_SECONDARY_BUS_INSERT(x, y) \ + (((x) & ~PCI_SECONDARY_BUS_MASK ) | (((y) & 0xffu) << 8)) +#define PCI_SUBORDINATE_BUS_INSERT(x, y) \ + (((x) & ~PCI_SUBORDINATE_BUS_MASK) | (((y) & 0xffu) << 16)) + +/* Ditto for CardBus bridges */ +#define PCI_CB_PRIMARY_BUS_EXTRACT(x, tag) \ + PCI_PRIMARY_BUS_EXTRACT(x, tag) +#define PCI_CB_CARDBUS_BUS_EXTRACT(x, tag) \ + PCI_SECONDARY_BUS_EXTRACT(x, tag) +#define PCI_CB_SUBORDINATE_BUS_EXTRACT(x, tag) \ + PCI_SUBORDINATE_BUS_EXTRACT(x, tag) + +#define PCI_CB_PRIMARY_BUS_INSERT(x, tag) \ + PCI_PRIMARY_BUS_INSERT(x, tag) +#define PCI_CB_CARDBUS_BUS_INSERT(x, tag) \ + PCI_SECONDARY_BUS_INSERT(x, tag) +#define PCI_CB_SUBORDINATE_BUS_INSERT(x, tag) \ + PCI_SUBORDINATE_BUS_INSERT(x, tag) + +#if X_BYTE_ORDER == X_BIG_ENDIAN +#define PCI_CPU(val) (((val >> 24) & 0x000000ff) | \ + ((val >> 8) & 0x0000ff00) | \ + ((val << 8) & 0x00ff0000) | \ + ((val << 24) & 0xff000000)) +#else +#define PCI_CPU(val) (val) +#endif + +/* + * Debug Macros/Definitions + */ +/* #define DEBUGPCI 2 */ /* Disable/enable trace in PCI code */ + +#if defined(DEBUGPCI) + +# define PCITRACE(lvl,printfargs) \ + if (lvl > xf86Verbose) { \ + ErrorF printfargs; \ + } + +#else /* !defined(DEBUGPCI) */ + +# define PCITRACE(lvl,printfargs) + +#endif /* !defined(DEBUGPCI) */ + +/* + * PCI Config mechanism definitions + */ +#define PCI_EN 0x80000000 + +#define PCI_CFGMECH1_ADDRESS_REG 0xCF8 +#define PCI_CFGMECH1_DATA_REG 0xCFC + +#define PCI_CFGMECH1_MAXDEV 32 + +/* + * Select architecture specific PCI init function + */ +#if defined(__alpha__) +# if defined(linux) +# define ARCH_PCI_INIT axpPciInit +# define INCLUDE_XF86_MAP_PCI_MEM +# elif defined(__FreeBSD__) || defined(__OpenBSD__) +# define ARCH_PCI_INIT freebsdPciInit +# define INCLUDE_XF86_MAP_PCI_MEM +# define INCLUDE_XF86_NO_DOMAIN +# elif defined(__NetBSD__) +# define ARCH_PCI_INIT netbsdPciInit +# define INCLUDE_XF86_MAP_PCI_MEM +# define INCLUDE_XF86_NO_DOMAIN +# endif +#elif defined(__arm__) +# if defined(linux) +# define ARCH_PCI_INIT linuxPciInit +# define INCLUDE_XF86_MAP_PCI_MEM +# define INCLUDE_XF86_NO_DOMAIN +# endif +#elif defined(__hppa__) +# if defined(linux) +# define ARCH_PCI_INIT linuxPciInit +# define INCLUDE_XF86_MAP_PCI_MEM +# define INCLUDE_XF86_NO_DOMAIN +# endif +#elif defined(__ia64__) +# if defined(linux) +# define ARCH_PCI_INIT linuxPciInit +# define INCLUDE_XF86_MAP_PCI_MEM +# define INCLUDE_XF86_NO_DOMAIN +# endif +# define XF86SCANPCI_WRAPPER ia64ScanPCIWrapper +#elif defined(__i386__) +# define ARCH_PCI_INIT ix86PciInit +# define ARCH_PCI_HOST_BRIDGE ix86PciHostBridge +# define INCLUDE_XF86_MAP_PCI_MEM +# define INCLUDE_XF86_NO_DOMAIN +# if defined(linux) +# define ARCH_PCI_OS_INIT linuxPciInit +# endif +#elif defined(__mc68000__) +# if defined(linux) +# define ARCH_PCI_INIT linuxPciInit +# define INCLUDE_XF86_MAP_PCI_MEM +# define INCLUDE_XF86_NO_DOMAIN +# endif +#elif defined(__mips__) +# if defined(linux) +# define ARCH_PCI_INIT linuxPciInit +# define INCLUDE_XF86_MAP_PCI_MEM +# define INCLUDE_XF86_NO_DOMAIN +# endif +#elif defined(__powerpc__) +# if defined(linux) +# define ARCH_PCI_INIT linuxPciInit +# define INCLUDE_XF86_MAP_PCI_MEM +# define INCLUDE_XF86_NO_DOMAIN /* Needs kernel work to remove */ +# elif defined(__OpenBSD__) +# define ARCH_PCI_INIT freebsdPciInit +# define INCLUDE_XF86_MAP_PCI_MEM +# define INCLUDE_XF86_NO_DOMAIN +# elif defined(__NetBSD__) +# define ARCH_PCI_INIT netbsdPciInit +# define INCLUDE_XF86_MAP_PCI_MEM +# define INCLUDE_XF86_NO_DOMAIN +# elif defined(PowerMAX_OS) /* This port is broken */ +# define ARCH_PCI_INIT ppcPciInit +# else +# define ARCH_PCI_INIT ppcPciInit +# define INCLUDE_XF86_MAP_PCI_MEM +# define INCLUDE_XF86_NO_DOMAIN +# endif +#elif defined(__s390__) +# if defined(linux) +# define ARCH_PCI_INIT linuxPciInit +# define INCLUDE_XF86_MAP_PCI_MEM +# define INCLUDE_XF86_NO_DOMAIN +# endif +#elif defined(__sh__) +# if defined(linux) +# define ARCH_PCI_INIT linuxPciInit +# define INCLUDE_XF86_MAP_PCI_MEM +# define INCLUDE_XF86_NO_DOMAIN +# endif +#elif defined(__sparc__) +# if defined(linux) +# define ARCH_PCI_INIT linuxPciInit +# define INCLUDE_XF86_MAP_PCI_MEM +# elif defined(sun) +# define ARCH_PCI_INIT sparcPciInit +# define INCLUDE_XF86_MAP_PCI_MEM +# elif defined(__OpenBSD__) && defined(__sparc64__) +# define ARCH_PCI_INIT freebsdPciInit +# define INCLUDE_XF86_MAP_PCI_MEM +# define INCLUDE_XF86_NO_DOMAIN +# endif +# define ARCH_PCI_PCI_BRIDGE sparcPciPciBridge +#elif defined(__x86_64__) +# define ARCH_PCI_INIT ix86PciInit +# define INCLUDE_XF86_MAP_PCI_MEM +# define INCLUDE_XF86_NO_DOMAIN +# if defined(linux) +# define ARCH_PCI_OS_INIT linuxPciInit +# endif +#endif + +#ifndef ARCH_PCI_INIT +#error No PCI support available for this architecture/OS combination +#endif + +extern void ARCH_PCI_INIT(void); +#if defined(ARCH_PCI_OS_INIT) +extern void ARCH_PCI_OS_INIT(void); +#endif + +#if defined(ARCH_PCI_HOST_BRIDGE) +extern void ARCH_PCI_HOST_BRIDGE(pciConfigPtr pPCI); +#endif + +#if defined(ARCH_PCI_PCI_BRIDGE) +extern void ARCH_PCI_PCI_BRIDGE(pciConfigPtr pPCI); +#endif + +#if defined(XF86SCANPCI_WRAPPER) +typedef enum { + SCANPCI_INIT, + SCANPCI_TERM +} scanpciWrapperOpt; +extern void XF86SCANPCI_WRAPPER(scanpciWrapperOpt flags); +#endif + +/* + * Table of functions used to access a specific PCI bus domain + * (e.g. a primary PCI bus and all of its secondaries) + */ +typedef struct pci_bus_funcs { + CARD32 (*pciReadLong)(PCITAG, int); + void (*pciWriteLong)(PCITAG, int, CARD32); + void (*pciSetBitsLong)(PCITAG, int, CARD32, CARD32); + ADDRESS (*pciAddrHostToBus)(PCITAG, PciAddrType, ADDRESS); + ADDRESS (*pciAddrBusToHost)(PCITAG, PciAddrType, ADDRESS); + /* + * The next three are optional. If NULL, the corresponding function is + * to be performed generically. + */ + CARD16 (*pciControlBridge)(int, CARD16, CARD16); + void (*pciGetBridgeBusses)(int, int *, int *, int *); + /* Use pointer's to avoid #include recursion */ + void (*pciGetBridgeResources)(int, pointer *, pointer *, pointer *); +} pciBusFuncs_t, *pciBusFuncs_p; + +/* + * pciBusInfo_t - One structure per defined PCI bus + */ +typedef struct pci_bus_info { + unsigned char configMech; /* PCI config type to use */ + unsigned char numDevices; /* Range of valid devnums */ + unsigned char secondary; /* Boolean: bus is a secondary */ + int primary_bus; /* Parent bus */ +#ifdef PowerMAX_OS + unsigned long ppc_io_base; /* PowerPC I/O spc membase */ + unsigned long ppc_io_size; /* PowerPC I/O spc size */ +#endif + pciBusFuncs_p funcs; /* PCI access functions */ + void *pciBusPriv; /* Implementation private data */ + pciConfigPtr bridge; /* bridge that opens this bus */ +} pciBusInfo_t; + +#define HOST_NO_BUS ((pciBusInfo_t *)(-1)) + +/* configMech values */ +#define PCI_CFG_MECH_UNKNOWN 0 /* Not yet known */ +#define PCI_CFG_MECH_1 1 /* Most machines */ +#define PCI_CFG_MECH_2 2 /* Older PC's */ +#define PCI_CFG_MECH_OTHER 3 /* Something else */ + +/* Generic PCI service functions and helpers */ +PCITAG pciGenFindFirst(void); +PCITAG pciGenFindNext(void); +CARD32 pciCfgMech1Read(PCITAG tag, int offset); +void pciCfgMech1Write(PCITAG tag, int offset, CARD32 val); +void pciCfgMech1SetBits(PCITAG tag, int offset, CARD32 mask, + CARD32 val); +CARD32 pciByteSwap(CARD32); +Bool pciMfDev(int, int); +ADDRESS pciAddrNOOP(PCITAG tag, PciAddrType type, ADDRESS); + +extern PCITAG (*pciFindFirstFP)(void); +extern PCITAG (*pciFindNextFP)(void); + +extern CARD32 pciDevid; +extern CARD32 pciDevidMask; + +extern int pciMaxBusNum; + +extern int pciBusNum; +extern int pciDevNum; +extern int pciFuncNum; +extern PCITAG pciDeviceTag; + +extern pciBusInfo_t *pciBusInfo[]; + +#endif /* _PCI_H */ diff --git a/hw/xfree86/os-support/bus/Sbus.c b/hw/xfree86/os-support/bus/Sbus.c new file mode 100644 index 000000000..c730c1559 --- /dev/null +++ b/hw/xfree86/os-support/bus/Sbus.c @@ -0,0 +1,624 @@ +/* + * SBUS and OpenPROM access functions. + * + * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/Sbus.c,v 1.2 2001/10/28 03:34:01 tsi Exp $ */ + +#include <fcntl.h> +#include <stdio.h> +#include <unistd.h> +#include <stdlib.h> +#include <sys/ioctl.h> +#include <sys/mman.h> +#ifdef sun +#include <sys/utsname.h> +#endif +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +#include "xf86sbusBus.h" +#include "xf86Sbus.h" + +int promRootNode; + +static int promFd = -1; +static int promCurrentNode; +static int promOpenCount = 0; +static int promP1275 = -1; +#define MAX_PROP 128 +#define MAX_VAL (4096-128-4) +static struct openpromio *promOpio; + +sbusDevicePtr *xf86SbusInfo = NULL; + +struct sbus_devtable sbusDeviceTable[] = { + { SBUS_DEVICE_BW2, FBTYPE_SUN2BW, "bwtwo", "Sun Monochrome (bwtwo)" }, + { SBUS_DEVICE_CG2, FBTYPE_SUN2COLOR, "cgtwo", "Sun Color2 (cgtwo)" }, + { SBUS_DEVICE_CG3, FBTYPE_SUN3COLOR, "cgthree", "Sun Color3 (cgthree)" }, + { SBUS_DEVICE_CG4, FBTYPE_SUN4COLOR, "cgfour", "Sun Color4 (cgfour)" }, + { SBUS_DEVICE_CG6, FBTYPE_SUNFAST_COLOR, "cgsix", "Sun GX" }, + { SBUS_DEVICE_CG8, FBTYPE_MEMCOLOR, "cgeight", "Sun CG8/RasterOps" }, + { SBUS_DEVICE_CG12, FBTYPE_SUNGP3, "cgtwelve", "Sun GS (cgtwelve)" }, + { SBUS_DEVICE_CG14, FBTYPE_MDICOLOR, "cgfourteen", "Sun SX" }, + { SBUS_DEVICE_GT, FBTYPE_SUNGT, "gt", "Sun Graphics Tower" }, + { SBUS_DEVICE_MGX, -1, "mgx", "Quantum 3D MGXplus" }, + { SBUS_DEVICE_LEO, FBTYPE_SUNLEO, "leo", "Sun ZX or Turbo ZX" }, + { SBUS_DEVICE_TCX, FBTYPE_TCXCOLOR, "tcx", "Sun TCX" }, + { SBUS_DEVICE_FFB, FBTYPE_CREATOR, "ffb", "Sun FFB" }, + { SBUS_DEVICE_FFB, FBTYPE_CREATOR, "afb", "Sun Elite3D" }, + { 0, 0, NULL } +}; + +int +promGetSibling(int node) +{ + promOpio->oprom_size = sizeof(int); + + if (node == -1) return 0; + *(int *)promOpio->oprom_array = node; + if (ioctl(promFd, OPROMNEXT, promOpio) < 0) + return 0; + promCurrentNode = *(int *)promOpio->oprom_array; + return *(int *)promOpio->oprom_array; +} + +int +promGetChild(int node) +{ + promOpio->oprom_size = sizeof(int); + + if (!node || node == -1) return 0; + *(int *)promOpio->oprom_array = node; + if (ioctl(promFd, OPROMCHILD, promOpio) < 0) + return 0; + promCurrentNode = *(int *)promOpio->oprom_array; + return *(int *)promOpio->oprom_array; +} + +char * +promGetProperty(const char *prop, int *lenp) +{ + promOpio->oprom_size = MAX_VAL; + + strcpy(promOpio->oprom_array, prop); + if (ioctl(promFd, OPROMGETPROP, promOpio) < 0) + return 0; + if (lenp) *lenp = promOpio->oprom_size; + return promOpio->oprom_array; +} + +int +promGetBool(const char *prop) +{ + promOpio->oprom_size = 0; + + *(int *)promOpio->oprom_array = 0; + for (;;) { + promOpio->oprom_size = MAX_PROP; + if (ioctl(promFd, OPROMNXTPROP, promOpio) < 0) + return 0; + if (!promOpio->oprom_size) + return 0; + if (!strcmp(promOpio->oprom_array, prop)) + return 1; + } +} + +#define PROM_NODE_SIBLING 0x01 +#define PROM_NODE_PREF 0x02 +#define PROM_NODE_SBUS 0x04 +#define PROM_NODE_EBUS 0x08 +#define PROM_NODE_PCI 0x10 + +static int +promSetNode(sbusPromNodePtr pnode) +{ + int node; + + if (!pnode->node || pnode->node == -1) + return -1; + if (pnode->cookie[0] & PROM_NODE_SIBLING) + node = promGetSibling(pnode->cookie[1]); + else + node = promGetChild(pnode->cookie[1]); + if (pnode->node != node) + return -1; + return 0; +} + +static void +promIsP1275(void) +{ +#ifdef linux + FILE *f; + char buffer[1024]; + + if (promP1275 != -1) + return; + promP1275 = 0; + f = fopen("/proc/cpuinfo","r"); + if (!f) return; + while (fgets(buffer, 1024, f) != NULL) + if (!strncmp (buffer, "type", 4) && strstr (buffer, "sun4u")) { + promP1275 = 1; + break; + } + fclose(f); +#elif defined(sun) + struct utsname buffer; + + if ((uname(&buffer) == 0) && !strcmp(buffer.machine, "sun4u")) + promP1275 = TRUE; + else + promP1275 = FALSE; +#else +#error Missing promIsP1275() function for this OS +#endif +} + +void +sparcPromClose(void) +{ + if (promOpenCount > 1) { + promOpenCount--; + return; + } + if (promFd != -1) { + close(promFd); + promFd = -1; + } + if (promOpio) { + xfree(promOpio); + promOpio = NULL; + } + promOpenCount = 0; +} + +int +sparcPromInit(void) +{ + if (promOpenCount) { + promOpenCount++; + return 0; + } + promFd = open("/dev/openprom", O_RDONLY, 0); + if (promFd == -1) + return -1; + promOpio = (struct openpromio *)xalloc(4096); + if (!promOpio) { + sparcPromClose(); + return -1; + } + promRootNode = promGetSibling(0); + if (!promRootNode) { + sparcPromClose(); + return -1; + } + promIsP1275(); + promOpenCount++; + + return 0; +} + +char * +sparcPromGetProperty(sbusPromNodePtr pnode, const char *prop, int *lenp) +{ + if (promSetNode(pnode)) + return NULL; + return promGetProperty(prop, lenp); +} + +int +sparcPromGetBool(sbusPromNodePtr pnode, const char *prop) +{ + if (promSetNode(pnode)) + return 0; + return promGetBool(prop); +} + +static void +promWalkAssignNodes(int node, int oldnode, int flags, sbusDevicePtr *devicePtrs) +{ + int nextnode; + int len, sbus = flags & PROM_NODE_SBUS; + char *prop; + int devId, i, j; + sbusPromNode pNode, pNode2; + + prop = promGetProperty("device_type", &len); + if (prop && (len > 0)) do { + if (!strcmp(prop, "display")) { + prop = promGetProperty("name", &len); + if (!prop || len <= 0) + break; + while ((*prop >= 'A' && *prop <= 'Z') || *prop == ',') + prop++; + for (i = 0; sbusDeviceTable[i].devId; i++) + if (!strcmp(prop, sbusDeviceTable[i].promName)) + break; + devId = sbusDeviceTable[i].devId; + if (!devId) + break; + if (!sbus) { + if (devId == SBUS_DEVICE_FFB) { + /* + * All /SUNW,ffb outside of SBUS tree come before all + * /SUNW,afb outside of SBUS tree in Linux. + */ + if (!strcmp(prop, "afb")) + flags |= PROM_NODE_PREF; + } else if (devId != SBUS_DEVICE_CG14) + break; + } + for (i = 0; i < 32; i++) { + if (!devicePtrs[i] || devicePtrs[i]->devId != devId) + continue; + if (devicePtrs[i]->node.node) { + if ((devicePtrs[i]->node.cookie[0] & ~PROM_NODE_SIBLING) <= + (flags & ~PROM_NODE_SIBLING)) + continue; + for (j = i + 1, pNode = devicePtrs[i]->node; j < 32; j++) { + if (!devicePtrs[j] || devicePtrs[j]->devId != devId) + continue; + pNode2 = devicePtrs[j]->node; + devicePtrs[j]->node = pNode; + pNode = pNode2; + } + } + devicePtrs[i]->node.node = node; + devicePtrs[i]->node.cookie[0] = flags; + devicePtrs[i]->node.cookie[1] = oldnode; + break; + } + break; + } + } while (0); + + prop = promGetProperty("name", &len); + if (prop && len > 0) { + if (!strcmp(prop, "sbus") || !strcmp(prop, "sbi")) + sbus = PROM_NODE_SBUS; + } + + nextnode = promGetChild(node); + if (nextnode) + promWalkAssignNodes(nextnode, node, sbus, devicePtrs); + + nextnode = promGetSibling(node); + if (nextnode) + promWalkAssignNodes(nextnode, node, PROM_NODE_SIBLING | sbus, devicePtrs); +} + +void +sparcPromAssignNodes(void) +{ + sbusDevicePtr psdp, *psdpp; + int n, holes = 0, i, j; + FILE *f; + sbusDevicePtr devicePtrs[32]; + + (void)memset(devicePtrs, 0, sizeof(devicePtrs)); + for (psdpp = xf86SbusInfo, n = 0; (psdp = *psdpp); psdpp++, n++) { + if (psdp->fbNum != n) + holes = 1; + devicePtrs[psdp->fbNum] = psdp; + } + if (holes && (f = fopen("/proc/fb", "r")) != NULL) { + /* We could not open one of fb devices, check /proc/fb to see what + * were the types of the cards missed. */ + char buffer[64]; + int fbNum, devId; + static struct { + int devId; + char *prefix; + } procFbPrefixes[] = { + { SBUS_DEVICE_BW2, "BWtwo" }, + { SBUS_DEVICE_CG14, "CGfourteen" }, + { SBUS_DEVICE_CG6, "CGsix" }, + { SBUS_DEVICE_CG3, "CGthree" }, + { SBUS_DEVICE_FFB, "Creator" }, + { SBUS_DEVICE_FFB, "Elite 3D" }, + { SBUS_DEVICE_LEO, "Leo" }, + { SBUS_DEVICE_TCX, "TCX" }, + { 0, NULL }, + }; + + while (fscanf(f, "%d %63s\n", &fbNum, buffer) == 2) { + for (i = 0; procFbPrefixes[i].devId; i++) + if (! strncmp(procFbPrefixes[i].prefix, buffer, + strlen(procFbPrefixes[i].prefix))) + break; + devId = procFbPrefixes[i].devId; + if (! devId) continue; + if (devicePtrs[fbNum]) { + if (devicePtrs[fbNum]->devId != devId) + xf86ErrorF("Inconsistent /proc/fb with FBIOGATTR\n"); + } else if (!devicePtrs[fbNum]) { + devicePtrs[fbNum] = psdp = xnfcalloc(sizeof (sbusDevice), 1); + psdp->devId = devId; + psdp->fbNum = fbNum; + psdp->fd = -2; + } + } + fclose(f); + } + promGetSibling(0); + promWalkAssignNodes(promRootNode, 0, PROM_NODE_PREF, devicePtrs); + for (i = 0, j = 0; i < 32; i++) + if (devicePtrs[i] && devicePtrs[i]->fbNum == -1) + j++; + xf86SbusInfo = xnfrealloc(xf86SbusInfo, sizeof(psdp) * (n + j + 1)); + for (i = 0, psdpp = xf86SbusInfo; i < 32; i++) + if (devicePtrs[i]) { + if (devicePtrs[i]->fbNum == -1) { + memmove(psdpp + 1, psdpp, sizeof(psdpp) * (n + 1)); + *psdpp = devicePtrs[i]; + } else + n--; + } +} + +static char * +promGetReg(int type) +{ + char *prop; + int len; + static char regstr[40]; + + regstr[0] = 0; + prop = promGetProperty("reg", &len); + if (prop && len >= 4) { + unsigned int *reg = (unsigned int *)prop; + if (!promP1275 || (type == PROM_NODE_SBUS) || (type == PROM_NODE_EBUS)) + sprintf (regstr, "@%x,%x", reg[0], reg[1]); + else if (type == PROM_NODE_PCI) { + if ((reg[0] >> 8) & 7) + sprintf (regstr, "@%x,%x", (reg[0] >> 11) & 0x1f, (reg[0] >> 8) & 7); + else + sprintf (regstr, "@%x", (reg[0] >> 11) & 0x1f); + } else if (len == 4) + sprintf (regstr, "@%x", reg[0]); + else { + unsigned int regs[2]; + + /* Things get more complicated on UPA. If upa-portid exists, + then address is @upa-portid,second-int-in-reg, otherwise + it is @first-int-in-reg/16,second-int-in-reg (well, probably + upa-portid always exists, but just to be safe). */ + memcpy (regs, reg, sizeof(regs)); + prop = promGetProperty("upa-portid", &len); + if (prop && len == 4) { + reg = (unsigned int *)prop; + sprintf (regstr, "@%x,%x", reg[0], regs[1]); + } else + sprintf (regstr, "@%x,%x", regs[0] >> 4, regs[1]); + } + } + return regstr; +} + +static int +promWalkNode2Pathname(char *path, int parent, int node, int searchNode, int type) +{ + int nextnode; + int len, ntype = type; + char *prop, *p; + + prop = promGetProperty("name", &len); + *path = '/'; + if (!prop || len <= 0) + return 0; + if ((!strcmp(prop, "sbus") || !strcmp(prop, "sbi")) && !type) + ntype = PROM_NODE_SBUS; + else if (!strcmp(prop, "ebus") && type == PROM_NODE_PCI) + ntype = PROM_NODE_EBUS; + else if (!strcmp(prop, "pci") && !type) + ntype = PROM_NODE_PCI; + strcpy (path + 1, prop); + p = promGetReg(type); + if (*p) + strcat (path, p); + if (node == searchNode) + return 1; + nextnode = promGetChild(node); + if (nextnode && + promWalkNode2Pathname(strchr(path, 0), node, nextnode, searchNode, ntype)) + return 1; + nextnode = promGetSibling(node); + if (nextnode && + promWalkNode2Pathname(path, parent, nextnode, searchNode, type)) + return 1; + return 0; +} + +char * +sparcPromNode2Pathname(sbusPromNodePtr pnode) +{ + char *ret; + + if (!pnode->node) return NULL; + ret = xalloc(4096); + if (!ret) return NULL; + if (promWalkNode2Pathname(ret, promRootNode, promGetChild(promRootNode), pnode->node, 0)) + return ret; + xfree(ret); + return NULL; +} + +static int +promWalkPathname2Node(char *name, char *regstr, int parent, int type) +{ + int len, node, ret; + char *prop, *p; + + for (;;) { + prop = promGetProperty("name", &len); + if (!prop || len <= 0) + return 0; + if ((!strcmp(prop, "sbus") || !strcmp(prop, "sbi")) && !type) + type = PROM_NODE_SBUS; + else if (!strcmp(prop, "ebus") && type == PROM_NODE_PCI) + type = PROM_NODE_EBUS; + else if (!strcmp(prop, "pci") && !type) + type = PROM_NODE_PCI; + for (node = promGetChild(parent); node; node = promGetSibling(node)) { + prop = promGetProperty("name", &len); + if (!prop || len <= 0) + continue; + if (*name && strcmp(name, prop)) + continue; + if (*regstr) { + p = promGetReg(type); + if (! *p || strcmp(p + 1, regstr)) + continue; + } + break; + } + if (!node) { + for (node = promGetChild(parent); node; node = promGetSibling(node)) { + ret = promWalkPathname2Node(name, regstr, node, type); + if (ret) return ret; + } + return 0; + } + name = strchr(regstr, 0) + 1; + if (! *name) + return node; + p = strchr(name, '/'); + if (p) + *p = 0; + else + p = strchr(name, 0); + regstr = strchr(name, '@'); + if (regstr) + *regstr++ = 0; + else + regstr = p; + if (name == regstr) + return 0; + parent = node; + } +} + +int +sparcPromPathname2Node(const char *pathName) +{ + int i; + char *name, *regstr, *p; + + i = strlen(pathName); + name = xalloc(i + 2); + if (! name) return 0; + strcpy (name, pathName); + name [i + 1] = 0; + if (name[0] != '/') + return 0; + p = strchr(name + 1, '/'); + if (p) + *p = 0; + else + p = strchr(name, 0); + regstr = strchr(name, '@'); + if (regstr) + *regstr++ = 0; + else + regstr = p; + if (name + 1 == regstr) + return 0; + promGetSibling(0); + i = promWalkPathname2Node(name + 1, regstr, promRootNode, 0); + xfree(name); + return i; +} + +pointer +xf86MapSbusMem(sbusDevicePtr psdp, unsigned long offset, unsigned long size) +{ + pointer ret; + + if (psdp->fd == -1) { + psdp->fd = open(psdp->device, O_RDWR); + if (psdp->fd == -1) + return NULL; + } else if (psdp->fd < 0) + return NULL; + + ret = (pointer) mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, + psdp->fd, offset); + if (ret == (pointer) -1) { + ret = (pointer) mmap (NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, + psdp->fd, offset); + } + if (ret == (pointer) -1) + return NULL; + + return ret; +} + +void +xf86UnmapSbusMem(sbusDevicePtr psdp, pointer addr, unsigned long size) +{ + munmap (addr, size); +} + +/* Tell OS that we are driving the HW cursor ourselves. */ +void +xf86SbusHideOsHwCursor(sbusDevicePtr psdp) +{ + struct fbcursor fbcursor; + unsigned char zeros[8]; + + memset(&fbcursor, 0, sizeof(fbcursor)); + memset(&zeros, 0, sizeof(zeros)); + fbcursor.cmap.count = 2; + fbcursor.cmap.red = zeros; + fbcursor.cmap.green = zeros; + fbcursor.cmap.blue = zeros; + fbcursor.image = (char *)zeros; + fbcursor.mask = (char *)zeros; + fbcursor.size.x = 32; + fbcursor.size.y = 1; + fbcursor.set = FB_CUR_SETALL; + ioctl(psdp->fd, FBIOSCURSOR, &fbcursor); +} + +/* Set HW cursor colormap. */ +void +xf86SbusSetOsHwCursorCmap(sbusDevicePtr psdp, int bg, int fg) +{ + struct fbcursor fbcursor; + unsigned char red[2], green[2], blue[2]; + + memset(&fbcursor, 0, sizeof(fbcursor)); + red[0] = bg >> 16; + green[0] = bg >> 8; + blue[0] = bg; + red[1] = fg >> 16; + green[1] = fg >> 8; + blue[1] = fg; + fbcursor.cmap.count = 2; + fbcursor.cmap.red = red; + fbcursor.cmap.green = green; + fbcursor.cmap.blue = blue; + fbcursor.set = FB_CUR_SETCMAP; + ioctl(psdp->fd, FBIOSCURSOR, &fbcursor); +} diff --git a/hw/xfree86/os-support/bus/axpPci.c b/hw/xfree86/os-support/bus/axpPci.c new file mode 100644 index 000000000..04ff8b956 --- /dev/null +++ b/hw/xfree86/os-support/bus/axpPci.c @@ -0,0 +1,474 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/axpPci.c,v 1.15 2002/12/12 04:12:02 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. + */ + +#include <stdio.h> +#include "compiler.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "Pci.h" + +#include <asm/unistd.h> +#include "../linux/lnx.h" /* for _iobase */ + +/* + * Alpha/Linux platform specific PCI access functions + */ +static CARD32 axpPciCfgRead(PCITAG tag, int off); +static void axpPciCfgWrite(PCITAG, int off, CARD32 val); +static void axpPciCfgSetBits(PCITAG tag, int off, CARD32 mask, CARD32 bits); + +static pciBusFuncs_t axpFuncs0 = { +/* pciReadLong */ axpPciCfgRead, +/* pciWriteLong */ axpPciCfgWrite, +/* pciSetBitsLong */ axpPciCfgSetBits, +/* pciAddrHostToBus */ pciAddrNOOP, +/* pciAddrBusToHost */ pciAddrNOOP +}; + +typedef struct _axpDomainRec { + int domain, hose; + int root_bus; + unsigned long dense_io, sparse_io; + unsigned long dense_mem, sparse_mem; + IOADDRESS mapped_io; +} axpDomainRec, *axpDomainPtr; + +#define MAX_DOMAINS (MAX_PCI_BUSES / 256) +static axpDomainPtr xf86DomainInfo[MAX_DOMAINS] = { NULL, }; +static int pciNumDomains = 0; + +/* + * For debug, domain assignment can start downward from a fixed base + * (instead of up from 0) by defining FORCE_HIGH_DOMAINS. This allows + * debug of large domain numbers and sparse domain numbering on systems + * which don't have as many hoses. + */ +#if 0 +# define FORCE_HIGH_DOMAINS MAX_DOMAINS /* assign domains downward from here */ +#endif + +/* + * If FORCE_HIGH_DOMAINS is set, make sure it's not larger than the + * max domain + */ +#if defined(FORCE_HIGH_DOMAINS) && (FORCE_HIGH_DOMAINS > MAX_DOMAINS) +# undef FORCE_HIGH_DOMAINS +# define FORCE_HIGH_DOMAINS MAX_DOMAINS +#endif + +static int +axpSetupDomains(void) +{ + axpDomainRec axpDomain; + int numDomains = 0; + int hose; + +#ifndef INCLUDE_XF86_NO_DOMAIN + +#ifdef FORCE_HIGH_DOMAINS + xf86Msg(X_WARNING, + "DEBUG OPTION FORCE_HIGH_DOMAINS in use - DRI will *NOT* work\n"); + numDomains = FORCE_HIGH_DOMAINS; +#endif + + /* + * Since each hose has a different address space, hoses are a perfect + * overlay for domains, so set up one domain for each hose present + * in the system. We have to loop through all possible hoses because + * some systems allow sparse I/O controllers. + */ + for(hose = 0; hose < MAX_DOMAINS; hose++) { + axpDomain.root_bus = _iobase(IOBASE_ROOT_BUS, hose, -1, -1); + if (axpDomain.root_bus < 0) continue; + + axpDomain.hose = hose; + +#ifndef FORCE_HIGH_DOMAINS + + axpDomain.domain = axpDomain.hose = hose; + numDomains = axpDomain.domain + 1; + +#else /* FORCE_HIGH_DOMAINS */ + + axpDomain.domain = numDomains - hose - 1; + + xf86Msg(X_WARNING, + "FORCE_HIGH_DOMAINS - assigned hose %d to domain %d\n", + axpDomain.hose, axpDomain.domain); + +#endif /* FORCE_HIGH_DOMAINS */ + + axpDomain.dense_io = _iobase(IOBASE_DENSE_IO, hose, -1, -1); + axpDomain.sparse_io = _iobase(IOBASE_SPARSE_IO, hose, -1, -1); + axpDomain.mapped_io = 0; + axpDomain.dense_mem = _iobase(IOBASE_DENSE_MEM, hose, -1, -1); + axpDomain.sparse_mem = _iobase(IOBASE_SPARSE_MEM, hose, -1, -1); + + xf86DomainInfo[axpDomain.domain] = xnfalloc(sizeof(axpDomainRec)); + *(xf86DomainInfo[axpDomain.domain]) = axpDomain; + + /* + * For now, only allow a single domain (hose) on sparse i/o systems. + * + * Allowing multiple domains on sparse systems would require: + * 1) either + * a) revamping the sparse video mapping code to allow + * for multiple unrelated address regions + * -- OR -- + * b) implementing sparse mapping directly in + * xf86MapDomainMemory + * 2) revaming read/write sparse routines to correctly handle + * the solution to 1) + * 3) implementing a sparse I/O system (mapping, inX/outX) + * independent of glibc, since the glibc version only + * supports hose 0 + */ + if (axpDomain.sparse_io) { + if (_iobase(IOBASE_ROOT_BUS, hose + 1, -1, -1) >= 0) { + /* + * It's a sparse i/o system with (at least) one more hose, + * show a message indicating that video is constrained to + * hose 0 + */ + xf86Msg(X_INFO, + "Sparse I/O system - constraining video to hose 0\n"); + } + break; + } + } + +#else /* INCLUDE_XF86_NO_DOMAIN */ + + /* + * domain support is not included, so just set up a single domain (0) + * to represent the first hose so that axpPciInit will still have + * be able to set up the root bus + */ + xf86DomainInfo[0] = xnfalloc(sizeof(axpDomainRec)); + *(xf86DomainInfo[0]) = axpDomain; + numDomains = 1; + +#endif /* INCLUDE_XF86_NO_DOMAIN */ + + return numDomains; +} + +void +axpPciInit() +{ + axpDomainPtr pDomain; + int domain, bus; + + pciNumDomains = axpSetupDomains(); + + for(domain = 0; domain < pciNumDomains; domain++) { + if (!(pDomain = xf86DomainInfo[domain])) continue; + + /* + * Since any bridged buses will be behind a probed pci-pci bridge, + * only set up the root bus for each domain (hose) and the bridged + * buses will be set up as they are found. + */ + bus = PCI_MAKE_BUS(domain, 0); + pciBusInfo[bus] = xnfalloc(sizeof(pciBusInfo_t)); + (void)memset(pciBusInfo[bus], 0, sizeof(pciBusInfo_t)); + + pciBusInfo[bus]->configMech = PCI_CFG_MECH_OTHER; + pciBusInfo[bus]->numDevices = 32; + pciBusInfo[bus]->funcs = &axpFuncs0; + pciBusInfo[bus]->pciBusPriv = pDomain; + + pciNumBuses = bus + 1; + } + + pciFindFirstFP = pciGenFindFirst; + pciFindNextFP = pciGenFindNext; +} + +/* + * Alpha/Linux PCI configuration space access routines + */ +static int +axpPciBusFromTag(PCITAG tag) +{ + pciBusInfo_t *pBusInfo; + axpDomainPtr pDomain; + int bus, dfn; + + bus = PCI_BUS_FROM_TAG(tag); + if ((bus >= pciNumBuses) + || !(pBusInfo = pciBusInfo[bus]) + || !(pDomain = pBusInfo->pciBusPriv) + || (pDomain->domain != PCI_DOM_FROM_TAG(tag))) return -1; + + bus = PCI_BUS_NO_DOMAIN(bus) + pDomain->root_bus; + dfn = PCI_DFN_FROM_TAG(tag); + if (_iobase(IOBASE_HOSE, -1, bus, dfn) != pDomain->hose) return -1; + + return bus; +} + +static CARD32 +axpPciCfgRead(PCITAG tag, int off) +{ + int bus, dfn; + CARD32 val = 0xffffffff; + + if ((bus = axpPciBusFromTag(tag)) >= 0) { + dfn = PCI_DFN_FROM_TAG(tag); + + syscall(__NR_pciconfig_read, bus, dfn, off, 4, &val); + } + return(val); +} + +static void +axpPciCfgWrite(PCITAG tag, int off, CARD32 val) +{ + int bus, dfn; + + if ((bus = axpPciBusFromTag(tag)) >= 0) { + dfn = PCI_DFN_FROM_TAG(tag); + syscall(__NR_pciconfig_write, bus, dfn, off, 4, &val); + } +} + +static void +axpPciCfgSetBits(PCITAG tag, int off, CARD32 mask, CARD32 bits) +{ + int bus, dfn; + CARD32 val = 0xffffffff; + + if ((bus = axpPciBusFromTag(tag)) >= 0) { + dfn = PCI_DFN_FROM_TAG(tag); + + syscall(__NR_pciconfig_read, bus, dfn, off, 4, &val); + val = (val & ~mask) | (bits & mask); + syscall(__NR_pciconfig_write, bus, dfn, off, 4, &val); + } +} + +#ifndef INCLUDE_XF86_NO_DOMAIN + +/* + * Alpha/Linux addressing domain support + */ + +int +xf86GetPciDomain(PCITAG Tag) +{ + return PCI_DOM_FROM_TAG(Tag); +} + +pointer +xf86MapDomainMemory(int ScreenNum, int Flags, PCITAG Tag, + ADDRESS Base, unsigned long Size) +{ + axpDomainPtr pDomain; + int domain = PCI_DOM_FROM_TAG(Tag); + + if ((domain < 0) || (domain >= pciNumDomains) || + !(pDomain = xf86DomainInfo[domain])) + FatalError("%s called with invalid parameters\n", __FUNCTION__); + + /* + * xf86MapVidMem already does what we need, but remember to subtract + * _bus_base() (the physical dense memory root of hose 0) since + * xf86MapVidMem is expecting an offset relative to _bus_base() rather + * than an actual physical address. + */ + return xf86MapVidMem(ScreenNum, Flags, + pDomain->dense_mem + Base - _bus_base(), Size); +} + +IOADDRESS +xf86MapDomainIO(int ScreenNum, int Flags, PCITAG Tag, + IOADDRESS Base, unsigned long Size) +{ + axpDomainPtr pDomain; + int domain = PCI_DOM_FROM_TAG(Tag); + + if ((domain < 0) || (domain >= pciNumDomains) || + !(pDomain = xf86DomainInfo[domain])) + FatalError("%s called with invalid parameters\n", __FUNCTION__); + + /* + * Use glibc inx/outx routines for sparse I/O, so just return the + * base [this is ok since we also constrain sparse I/O systems to + * a single domain in axpSetupDomains()] + */ + if (pDomain->sparse_io) return Base; + + /* + * I/O addresses on Alpha are really just different physical memory + * addresses that the system corelogic turns into I/O commands on the + * bus, so just use xf86MapVidMem to map I/O as well, but remember + * to subtract _bus_base() (the physical dense memory root of hose 0) + * since xf86MapVidMem is expecting an offset relative to _bus_base() + * rather than an actual physical address. + * + * Map the entire I/O space (64kB) at once and only once. + */ + if (!pDomain->mapped_io) + pDomain->mapped_io = (IOADDRESS)xf86MapVidMem(ScreenNum, Flags, + pDomain->dense_io - _bus_base(), + 0x10000); + + return pDomain->mapped_io + Base; +} + +int +xf86ReadDomainMemory(PCITAG Tag, ADDRESS Base, int Len, unsigned char *Buf) +{ + static unsigned long pagemask = 0; + unsigned char *MappedAddr; + unsigned long MapSize; + ADDRESS MapBase; + int i; + + if (!pagemask) pagemask = xf86getpagesize() - 1; + + /* Ensure page boundaries */ + MapBase = Base & ~pagemask; + MapSize = ((Base + Len + pagemask) & ~pagemask) - MapBase; + + /* + * VIDMEM_MMIO in order to get sparse mapping on sparse memory systems + * so we can use mmio functions to read (that way we can really get byte + * at a time reads on dense memory systems with byte/word instructions. + */ + MappedAddr = xf86MapDomainMemory(-1, VIDMEM_READONLY | VIDMEM_MMIO, + Tag, MapBase, MapSize); + + for (i = 0; i < Len; i++) { + *Buf++ = xf86ReadMmio8(MappedAddr, Base - MapBase + i); + } + + xf86UnMapVidMem(-1, MappedAddr, MapSize); + return Len; +} + +resPtr +xf86PciBusAccWindowsFromOS(void) +{ + resPtr pRes = NULL; + resRange range; + int domain; + + for(domain = 0; domain < pciNumDomains; domain++) { + if (!xf86DomainInfo[domain]) continue; + + RANGE(range, 0, 0xffffffffUL, + RANGE_TYPE(ResExcMemBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + + RANGE(range, 0, 0x0000ffffUL, + RANGE_TYPE(ResExcIoBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + } + + return pRes; +} + +resPtr +xf86BusAccWindowsFromOS(void) +{ + return xf86PciBusAccWindowsFromOS(); +} + +resPtr +xf86AccResFromOS(resPtr pRes) +{ + resRange range; + int domain; + + for(domain = 0; domain < pciNumDomains; domain++) { + if (!xf86DomainInfo[domain]) continue; + + /* + * Fallback is to claim the following areas: + * + * 0x000c0000 - 0x000effff location of VGA and other extensions ROMS + */ + + RANGE(range, 0x000c0000, 0x000effff, + RANGE_TYPE(ResExcMemBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + + /* + * Fallback would be to claim well known ports in the 0x0 - 0x3ff + * range along with their sparse I/O aliases, but that's too + * imprecise. Instead claim a bare minimum here. + */ + RANGE(range, 0x00000000, 0x000000ff, + RANGE_TYPE(ResExcIoBlock, domain)); /* For mainboard */ + pRes = xf86AddResToList(pRes, &range, -1); + + /* + * At minimum, the top and bottom resources must be claimed, so that + * resources that are (or appear to be) unallocated can be relocated. + */ + RANGE(range, 0x00000000, 0x00000000, + RANGE_TYPE(ResExcMemBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + RANGE(range, 0xffffffff, 0xffffffff, + RANGE_TYPE(ResExcMemBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); +/* RANGE(range, 0x00000000, 0x00000000, + RANGE_TYPE(ResExcIoBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); */ + RANGE(range, 0xffffffff, 0xffffffff, + RANGE_TYPE(ResExcIoBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + } + + return pRes; +} + +#endif /* !INCLUDE_XF86_NO_DOMAIN */ + diff --git a/hw/xfree86/os-support/bus/e8870PCI.c b/hw/xfree86/os-support/bus/e8870PCI.c new file mode 100644 index 000000000..829de03c0 --- /dev/null +++ b/hw/xfree86/os-support/bus/e8870PCI.c @@ -0,0 +1,54 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/e8870PCI.c,v 1.1 2003/02/23 20:26:49 tsi Exp $ */ +/* + * Copyright (C) 2002-2003 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ + +/* + * This file contains the glue necessary for support of Intel's E8870 chipset. + */ + +#include "e8870PCI.h" +#include "xf86.h" +#include "Pci.h" + +Bool +xf86PreScanE8870(void) +{ + PCITAG tag; + + /* Look for an E8870's Hub interface */ + tag = PCI_MAKE_TAG(0, 0x1E, 0); + if (pciReadLong(tag, PCI_ID_REG) != DEVID(INTEL, 82801_P2P)) + return FALSE; + + /* XXX Fill me in... */ + return TRUE; +} + +void +xf86PostScanE8870(void) +{ + /* XXX Fill me in... */ +} diff --git a/hw/xfree86/os-support/bus/e8870PCI.h b/hw/xfree86/os-support/bus/e8870PCI.h new file mode 100644 index 000000000..b910bcfd8 --- /dev/null +++ b/hw/xfree86/os-support/bus/e8870PCI.h @@ -0,0 +1,36 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/e8870PCI.h,v 1.1 2003/02/23 20:26:49 tsi Exp $ */ +/* + * Copyright (C) 2002-2003 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ + +#ifndef PCI_E8870_H +#define PCI_E8870_H 1 + +#include <X11/Xdefs.h> + +Bool xf86PreScanE8870(void); +void xf86PostScanE8870(void); + +#endif diff --git a/hw/xfree86/os-support/bus/freebsdPci.c b/hw/xfree86/os-support/bus/freebsdPci.c new file mode 100644 index 000000000..c3e621daf --- /dev/null +++ b/hw/xfree86/os-support/bus/freebsdPci.c @@ -0,0 +1,167 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/freebsdPci.c,v 1.5 2002/08/27 22:07:07 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. + */ + +#include <stdio.h> +#include "compiler.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "Pci.h" + +#include <sys/pciio.h> + +/* + * freebsd platform specific PCI access functions -- using /dev/pci + * needs kernel version 2.2.x + */ +static CARD32 freebsdPciCfgRead(PCITAG tag, int off); +static void freebsdPciCfgWrite(PCITAG, int off, CARD32 val); +static void freebsdPciCfgSetBits(PCITAG tag, int off, CARD32 mask, CARD32 bits); + +static pciBusFuncs_t freebsdFuncs0 = { +/* pciReadLong */ freebsdPciCfgRead, +/* pciWriteLong */ freebsdPciCfgWrite, +/* pciSetBitsLong */ freebsdPciCfgSetBits, +/* pciAddrHostToBus */ pciAddrNOOP, +/* pciAddrBusToHost */ pciAddrNOOP +}; + +static pciBusInfo_t freebsdPci0 = { +/* configMech */ PCI_CFG_MECH_OTHER, +/* numDevices */ 32, +/* secondary */ FALSE, +/* primary_bus */ 0, +#ifdef PowerMAX_OS +/* ppc_io_base */ 0, +/* ppc_io_size */ 0, +#endif +/* funcs */ &freebsdFuncs0, +/* pciBusPriv */ NULL, +/* bridge */ NULL +}; + +#if !defined(__OpenBSD__) +#if X_BYTE_ORDER == X_BIG_ENDIAN +#ifdef __sparc__ +#ifndef ASI_PL +#define ASI_PL 0x88 +#endif +#define PCI_CPU(val) ({ \ +int __ret; \ +__asm__ __volatile__("lduwa [%1] %2, %0" : "=r" (__ret) : "r" (&val), "i" (ASI_PL)); \ +__ret; \ +}) +#else +#define PCI_CPU(val) (((val >> 24) & 0x000000ff) | \ + ((val >> 8) & 0x0000ff00) | \ + ((val << 8) & 0x00ff0000) | \ + ((val << 24) & 0xff000000)) +#endif +#else +#define PCI_CPU(val) (val) +#endif +#else /* ! OpenBSD */ +/* OpenBSD has already the bytes in the right order + for all architectures */ +#define PCI_CPU(val) (val) +#endif + + +#define BUS(tag) (((tag)>>16)&0xff) +#define DFN(tag) (((tag)>>8)&0xff) + +static int pciFd = -1; + +void +freebsdPciInit() +{ + pciFd = open("/dev/pci", O_RDWR); + if (pciFd < 0) + return; + + pciNumBuses = 1; + pciBusInfo[0] = &freebsdPci0; + pciFindFirstFP = pciGenFindFirst; + pciFindNextFP = pciGenFindNext; +} + +static CARD32 +freebsdPciCfgRead(PCITAG tag, int off) +{ + struct pci_io io; + int error; + io.pi_sel.pc_bus = BUS(tag); + io.pi_sel.pc_dev = DFN(tag) >> 3; + io.pi_sel.pc_func = DFN(tag) & 7; + io.pi_reg = off; + io.pi_width = 4; + error = ioctl(pciFd, PCIOCREAD, &io); + if (error) + return ~0; + return PCI_CPU(io.pi_data); +} + +static void +freebsdPciCfgWrite(PCITAG tag, int off, CARD32 val) +{ + struct pci_io io; + io.pi_sel.pc_bus = BUS(tag); + io.pi_sel.pc_dev = DFN(tag) >> 3; + io.pi_sel.pc_func = DFN(tag) & 7; + io.pi_reg = off; + io.pi_width = 4; + io.pi_data = PCI_CPU(val); + ioctl(pciFd, PCIOCWRITE, &io); +} + +static void +freebsdPciCfgSetBits(PCITAG tag, int off, CARD32 mask, CARD32 bits) +{ + CARD32 val = freebsdPciCfgRead(tag, off); + val = (val & ~mask) | (bits & mask); + freebsdPciCfgWrite(tag, off, val); +} diff --git a/hw/xfree86/os-support/bus/ix86Pci.c b/hw/xfree86/os-support/bus/ix86Pci.c new file mode 100644 index 000000000..e07f5497c --- /dev/null +++ b/hw/xfree86/os-support/bus/ix86Pci.c @@ -0,0 +1,690 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/ix86Pci.c,v 1.18 2003/01/27 00:01:44 tsi Exp $ */ +/* + * ix86Pci.c - x86 PCI driver + * + * The XFree86 server PCI access functions have been reimplemented as a + * framework that allows each supported platform/OS to have their own + * platform/OS specific PCI driver. + * + * Most of the code of these functions was simply lifted from the + * Intel architecture specifric portion of the original Xfree86 + * PCI code in hw/xfree86/common_hw/xf86_PCI.C... + * + * Gary Barton + * Concurrent Computer Corporation + * garyb@gate.net + */ + +/* + * 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 software is derived from the original XFree86 PCI code + * which includes the following copyright notices as well: + * + * Copyright 1995 by Robin Cutshaw <robin@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 the above listed copyright holder(s) + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. The above listed + * copyright holder(s) make(s) no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM(S) ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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 code is also based heavily on the code in FreeBSD-current, which was + * written by Wolfgang Stanglmeier, and contains the following copyright: + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include <stdio.h> +#include "compiler.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "Pci.h" + +#ifdef PC98 +#define outb(port,data) _outb(port,data) +#define outl(port,data) _outl(port,data) +#define inb(port) _inb(port) +#define inl(port) _inl(port) +#endif + +#define PCI_CFGMECH2_ENABLE_REG 0xCF8 +#ifdef PC98 +#define PCI_CFGMECH2_FORWARD_REG 0xCF9 +#else +#define PCI_CFGMECH2_FORWARD_REG 0xCFA +#endif + +#define PCI_CFGMECH2_MAXDEV 16 + +#define PCI_ADDR_FROM_TAG_CFG1(tag,reg) (PCI_EN | tag | (reg & 0xfc)) +#define PCI_FORWARD_FROM_TAG(tag) PCI_BUS_FROM_TAG(tag) +#define PCI_ENABLE_FROM_TAG(tag) (0xf0 | (((tag) & 0x00000700) >> 7)) +#define PCI_ADDR_FROM_TAG_CFG2(tag,reg) (0xc000 | (((tag) & 0x0000f800) >> 3) \ + | (reg & 0xfc)) + +/* + * Intel x86 platform specific PCI access functions + */ +static CARD32 ix86PciReadLongSetup(PCITAG tag, int off); +static void ix86PciWriteLongSetup(PCITAG, int off, CARD32 val); +static void ix86PciSetBitsLongSetup(PCITAG, int off, CARD32 mask, CARD32 val); +static CARD32 ix86PciReadLongCFG1(PCITAG tag, int off); +static void ix86PciWriteLongCFG1(PCITAG, int off, CARD32 val); +static void ix86PciSetBitsLongCFG1(PCITAG, int off, CARD32 mask, CARD32 val); +static CARD32 ix86PciReadLongCFG2(PCITAG tag, int off); +static void ix86PciWriteLongCFG2(PCITAG, int off, CARD32 val); +static void ix86PciSetBitsLongCFG2(PCITAG, int off, CARD32 mask, CARD32 val); + +static pciBusFuncs_t ix86Funcs0 = { +/* pciReadLong */ ix86PciReadLongSetup, +/* pciWriteLong */ ix86PciWriteLongSetup, +/* pciSetBitsLong */ ix86PciSetBitsLongSetup, +/* pciAddrHostToBus */ pciAddrNOOP, +/* pciAddrBusToHost */ pciAddrNOOP +}; + +static pciBusFuncs_t ix86Funcs1 = { +/* pciReadLong */ ix86PciReadLongCFG1, +/* pciWriteLong */ ix86PciWriteLongCFG1, +/* pciSetBitsLong */ ix86PciSetBitsLongCFG1, +/* pciAddrHostToBus */ pciAddrNOOP, +/* pciAddrBusToHost */ pciAddrNOOP +}; + +static pciBusFuncs_t ix86Funcs2 = { +/* pciReadLong */ ix86PciReadLongCFG2, +/* pciWriteLong */ ix86PciWriteLongCFG2, +/* pciSetBitsLong */ ix86PciSetBitsLongCFG2, +/* pciAddrHostToBus */ pciAddrNOOP, +/* pciAddrBusToHost */ pciAddrNOOP +}; + +static pciBusInfo_t ix86Pci0 = { +/* configMech */ PCI_CFG_MECH_UNKNOWN, /* Set by ix86PciInit() */ +/* numDevices */ 0, /* Set by ix86PciInit() */ +/* secondary */ FALSE, +/* primary_bus */ 0, +#ifdef PowerMAX_OS +/* ppc_io_base */ 0, +/* ppc_io_size */ 0, +#endif +/* funcs */ &ix86Funcs0, /* Set by ix86PciInit() */ +/* pciBusPriv */ NULL, +/* bridge */ NULL +}; + +static Bool +ix86PciBusCheck(void) +{ + PCITAG tag; + CARD32 id, class; + CARD8 device; + + for (device = 0; device < ix86Pci0.numDevices; device++) { + tag = PCI_MAKE_TAG(0, device, 0); + id = (*ix86Pci0.funcs->pciReadLong)(tag, PCI_ID_REG); + + if ((CARD16)(id + 1U) <= (CARD16)1UL) + continue; + + /* The rest of this is inspired by the Linux kernel */ + class = (*ix86Pci0.funcs->pciReadLong)(tag, PCI_CLASS_REG); + + /* Ignore revision id and programming interface */ + switch (class >> 16) { + case (PCI_CLASS_PREHISTORIC << 8) | PCI_SUBCLASS_PREHISTORIC_MISC: + /* Check for vendors of known buggy chipsets */ + id &= 0x0000ffff; + if ((id == PCI_VENDOR_INTEL) || (id == PCI_VENDOR_COMPAQ)) + return TRUE; + continue; + + case (PCI_CLASS_PREHISTORIC << 8) | PCI_SUBCLASS_PREHISTORIC_VGA: + case (PCI_CLASS_DISPLAY << 8) | PCI_SUBCLASS_DISPLAY_VGA: + case (PCI_CLASS_BRIDGE << 8) | PCI_SUBCLASS_BRIDGE_HOST: + return TRUE; + + default: + break; + } + } + return FALSE; +} + +static +void ix86PciSelectCfgmech(void) +{ + static Bool beenhere = FALSE; + CARD32 mode1Res1 = 0, mode1Res2 = 0, oldVal1 = 0; + CARD8 mode2Res1 = 0, mode2Res2 = 0, oldVal2 = 0; + int stages = 0; + + if (beenhere) + return; /* Been there, done that */ + + beenhere = TRUE; + + /* + * Determine if motherboard chipset supports PCI Config Mech 1 or 2 + * We rely on xf86Info.pciFlags to tell which mechanisms to try.... + */ + switch (xf86Info.pciFlags) { + + case PCIProbe1: /* { */ + + xf86MsgVerb(X_INFO, 2, "PCI: Probing config type using method 1\n"); + oldVal1 = inl(PCI_CFGMECH1_ADDRESS_REG); + +#ifdef DEBUGPCI + if (xf86Verbose > 2) { + ErrorF("Checking config type 1:\n" + "\tinitial value of MODE1_ADDR_REG is 0x%08x\n", oldVal1); + ErrorF("\tChecking that all bits in mask 0x7f000000 are clear\n"); + } +#endif + + /* Assuming config type 1 to start with */ + if ((oldVal1 & 0x7f000000) == 0) { + + stages |= 0x01; + +#ifdef DEBUGPCI + if (xf86Verbose > 2) { + ErrorF("\tValue indicates possibly config type 1\n"); + ErrorF("\tWriting 32-bit value 0x%08x to MODE1_ADDR_REG\n", PCI_EN); +#if 0 + ErrorF("\tWriting 8-bit value 0x00 to MODE1_ADDR_REG + 3\n"); +#endif + } +#endif + + ix86Pci0.configMech = PCI_CFG_MECH_1; + ix86Pci0.numDevices = PCI_CFGMECH1_MAXDEV; + ix86Pci0.funcs = &ix86Funcs1; + + outl(PCI_CFGMECH1_ADDRESS_REG, PCI_EN); + +#if 0 + /* + * This seems to cause some Neptune-based PCI machines to switch + * from config type 1 to config type 2 + */ + outb(PCI_CFGMECH1_ADDRESS_REG + 3, 0); +#endif + mode1Res1 = inl(PCI_CFGMECH1_ADDRESS_REG); + +#ifdef DEBUGPCI + if (xf86Verbose > 2) { + ErrorF("\tValue read back from MODE1_ADDR_REG is 0x%08x\n", + mode1Res1); + ErrorF("\tRestoring original contents of MODE1_ADDR_REG\n"); + } +#endif + + outl(PCI_CFGMECH1_ADDRESS_REG, oldVal1); + + if (mode1Res1) { + + stages |= 0x02; + +#ifdef DEBUGPCI + if (xf86Verbose > 2) { + ErrorF("\tValue read back is non-zero, and indicates possible" + " config type 1\n"); + } +#endif + + if (ix86PciBusCheck()) { + +#ifdef DEBUGPCI + if (xf86Verbose > 2) + ErrorF("\tBus check Confirms this: "); +#endif + + xf86MsgVerb(X_INFO, 2, "PCI: Config type is 1\n"); + xf86MsgVerb(X_INFO, 3, + "PCI: stages = 0x%02x, oldVal1 = 0x%08x, mode1Res1" + " = 0x%08x\n", stages, oldVal1, mode1Res1); + return; + } + +#ifdef DEBUGPCI + if (xf86Verbose > 2) { + ErrorF("\tBus check fails to confirm this, continuing type 1" + " check ...\n"); + } +#endif + + } + + stages |= 0x04; + +#ifdef DEBUGPCI + if (xf86Verbose > 2) { + ErrorF("\tWriting 0xff000001 to MODE1_ADDR_REG\n"); + } +#endif + outl(PCI_CFGMECH1_ADDRESS_REG, 0xff000001); + mode1Res2 = inl(PCI_CFGMECH1_ADDRESS_REG); + +#ifdef DEBUGPCI + if (xf86Verbose > 2) { + ErrorF("\tValue read back from MODE1_ADDR_REG is 0x%08x\n", + mode1Res2); + ErrorF("\tRestoring original contents of MODE1_ADDR_REG\n"); + } +#endif + + outl(PCI_CFGMECH1_ADDRESS_REG, oldVal1); + + if ((mode1Res2 & 0x80000001) == 0x80000000) { + + stages |= 0x08; + +#ifdef DEBUGPCI + if (xf86Verbose > 2) { + ErrorF("\tValue read back has only the msb set\n" + "\tThis indicates possible config type 1\n"); + } +#endif + + if (ix86PciBusCheck()) { + +#ifdef DEBUGPCI + if (xf86Verbose > 2) + ErrorF("\tBus check Confirms this: "); +#endif + + xf86MsgVerb(X_INFO, 2, "PCI: Config type is 1\n"); + xf86MsgVerb(X_INFO, 3, + "PCI: stages = 0x%02x, oldVal1 = 0x%08x,\n" + "\tmode1Res1 = 0x%08x, mode1Res2 = 0x%08x\n", + stages, oldVal1, mode1Res1, mode1Res2); + return; + } + +#ifdef DEBUGPCI + if (xf86Verbose > 2) { + ErrorF("\tBus check fails to confirm this.\n"); + } +#endif + + } + } + + xf86MsgVerb(X_INFO, 3, "PCI: Standard check for type 1 failed.\n"); + xf86MsgVerb(X_INFO, 3, "PCI: stages = 0x%02x, oldVal1 = 0x%08x,\n" + "\tmode1Res1 = 0x%08x, mode1Res2 = 0x%08x\n", + stages, oldVal1, mode1Res1, mode1Res2); + + /* Try config type 2 */ + oldVal2 = inb(PCI_CFGMECH2_ENABLE_REG); + if ((oldVal2 & 0xf0) == 0) { + ix86Pci0.configMech = PCI_CFG_MECH_2; + ix86Pci0.numDevices = PCI_CFGMECH2_MAXDEV; + ix86Pci0.funcs = &ix86Funcs2; + + outb(PCI_CFGMECH2_ENABLE_REG, 0x0e); + mode2Res1 = inb(PCI_CFGMECH2_ENABLE_REG); + outb(PCI_CFGMECH2_ENABLE_REG, oldVal2); + + if (mode2Res1 == 0x0e) { + if (ix86PciBusCheck()) { + xf86MsgVerb(X_INFO, 2, "PCI: Config type is 2\n"); + return; + } + } + } + break; /* } */ + + case PCIProbe2: /* { */ + + /* The scanpci-style detection method */ + + xf86MsgVerb(X_INFO, 2, "PCI: Probing config type using method 2\n"); + + outb(PCI_CFGMECH2_ENABLE_REG, 0x00); + outb(PCI_CFGMECH2_FORWARD_REG, 0x00); + mode2Res1 = inb(PCI_CFGMECH2_ENABLE_REG); + mode2Res2 = inb(PCI_CFGMECH2_FORWARD_REG); + + if (mode2Res1 == 0 && mode2Res2 == 0) { + xf86MsgVerb(X_INFO, 2, "PCI: Config type is 2\n"); + ix86Pci0.configMech = PCI_CFG_MECH_2; + ix86Pci0.numDevices = PCI_CFGMECH2_MAXDEV; + ix86Pci0.funcs = &ix86Funcs2; + return; + } + + oldVal1 = inl(PCI_CFGMECH1_ADDRESS_REG); + outl(PCI_CFGMECH1_ADDRESS_REG, PCI_EN); + mode1Res1 = inl(PCI_CFGMECH1_ADDRESS_REG); + outl(PCI_CFGMECH1_ADDRESS_REG, oldVal1); + if (mode1Res1 == PCI_EN) { + xf86MsgVerb(X_INFO, 2, "PCI: Config type is 1\n"); + ix86Pci0.configMech = PCI_CFG_MECH_1; + ix86Pci0.numDevices = PCI_CFGMECH1_MAXDEV; + ix86Pci0.funcs = &ix86Funcs1; + return; + } + break; /* } */ + + case PCIForceConfig1: + + xf86MsgVerb(X_INFO, 2, "PCI: Forcing config type 1\n"); + + ix86Pci0.configMech = PCI_CFG_MECH_1; + ix86Pci0.numDevices = PCI_CFGMECH1_MAXDEV; + ix86Pci0.funcs = &ix86Funcs1; + return; + + case PCIForceConfig2: + + xf86MsgVerb(X_INFO, 2, "PCI: Forcing config type 2\n"); + + ix86Pci0.configMech = PCI_CFG_MECH_2; + ix86Pci0.numDevices = PCI_CFGMECH2_MAXDEV; + ix86Pci0.funcs = &ix86Funcs2; + return; + + case PCIOsConfig: + return; + + case PCIForceNone: + break; + } + + /* No PCI found */ + ix86Pci0.configMech = PCI_CFG_MECH_UNKNOWN; + xf86MsgVerb(X_INFO, 2, "PCI: No PCI bus found or probed for\n"); +} + +#if 0 +static pciTagRec +ix86PcibusTag(CARD8 bus, CARD8 cardnum, CARD8 func) +{ + pciTagRec tag; + + tag.cfg1 = 0; + + if (func > 7 || cardnum >= pciBusInfo[bus]->numDevices) + return tag; + + switch (ix86Pci0.configMech) { + case PCI_CFG_MECH_1: + tag.cfg1 = PCI_EN | ((CARD32)bus << 16) | + ((CARD32)cardnum << 11) | + ((CARD32)func << 8); + break; + + case PCI_CFG_MECH_2: + tag.cfg2.port = 0xc000 | ((CARD16)cardnum << 8); + tag.cfg2.enable = 0xf0 | (func << 1); + tag.cfg2.forward = bus; + break; + } + + return tag; +} +#endif + +static CARD32 +ix86PciReadLongSetup(PCITAG Tag, int reg) +{ + ix86PciSelectCfgmech(); + return (*ix86Pci0.funcs->pciReadLong)(Tag,reg); +} + +static CARD32 +ix86PciReadLongCFG1(PCITAG Tag, int reg) +{ + CARD32 addr, data = 0; + +#ifdef DEBUGPCI + ErrorF("ix86PciReadLong 0x%lx, %d\n", Tag, reg); +#endif + + addr = PCI_ADDR_FROM_TAG_CFG1(Tag,reg); + outl(PCI_CFGMECH1_ADDRESS_REG, addr); + data = inl(PCI_CFGMECH1_DATA_REG); + outl(PCI_CFGMECH1_ADDRESS_REG, 0); + +#ifdef DEBUGPCI + ErrorF("ix86PciReadLong 0x%lx\n", data); +#endif + + return data; +} + +static CARD32 +ix86PciReadLongCFG2(PCITAG Tag, int reg) +{ + CARD32 addr, data = 0; + CARD8 forward, enable; + +#ifdef DEBUGPCI + ErrorF("ix86PciReadLong 0x%lx, %d\n", Tag, reg); +#endif + + forward = PCI_FORWARD_FROM_TAG(Tag); + enable = PCI_ENABLE_FROM_TAG(Tag); + addr = PCI_ADDR_FROM_TAG_CFG2(Tag,reg); + + outb(PCI_CFGMECH2_ENABLE_REG, enable); + outb(PCI_CFGMECH2_FORWARD_REG, forward); + data = inl((CARD16)addr); + outb(PCI_CFGMECH2_ENABLE_REG, 0); + outb(PCI_CFGMECH2_FORWARD_REG, 0); + +#ifdef DEBUGPCI + ErrorF("ix86PciReadLong 0x%lx\n", data); +#endif + + return data; +} + +static void +ix86PciWriteLongSetup(PCITAG Tag, int reg, CARD32 data) +{ + ix86PciSelectCfgmech(); + (*ix86Pci0.funcs->pciWriteLong)(Tag,reg,data); +} + +static void +ix86PciWriteLongCFG1(PCITAG Tag, int reg, CARD32 data) +{ + CARD32 addr; + + addr = PCI_ADDR_FROM_TAG_CFG1(Tag,reg); + outl(PCI_CFGMECH1_ADDRESS_REG, addr); + outl(PCI_CFGMECH1_DATA_REG, data); + outl(PCI_CFGMECH1_ADDRESS_REG, 0); +} + +static void +ix86PciWriteLongCFG2(PCITAG Tag, int reg, CARD32 data) +{ + CARD32 addr; + CARD8 forward, enable; + + forward = PCI_FORWARD_FROM_TAG(Tag); + enable = PCI_ENABLE_FROM_TAG(Tag); + addr = PCI_ADDR_FROM_TAG_CFG2(Tag,reg); + + outb(PCI_CFGMECH2_ENABLE_REG, enable); + outb(PCI_CFGMECH2_FORWARD_REG, forward); + outl((CARD16)addr, data); + outb(PCI_CFGMECH2_ENABLE_REG, 0); + outb(PCI_CFGMECH2_FORWARD_REG, 0); +} + +static void +ix86PciSetBitsLongSetup(PCITAG Tag, int reg, CARD32 mask, CARD32 val) +{ + ix86PciSelectCfgmech(); + (*ix86Pci0.funcs->pciSetBitsLong)(Tag,reg,mask,val); +} + +static void +ix86PciSetBitsLongCFG1(PCITAG Tag, int reg, CARD32 mask, CARD32 val) +{ + CARD32 addr, data = 0; + +#ifdef DEBUGPCI + ErrorF("ix86PciSetBitsLong 0x%lx, %d\n", Tag, reg); +#endif + + addr = PCI_ADDR_FROM_TAG_CFG1(Tag,reg); + outl(PCI_CFGMECH1_ADDRESS_REG, addr); + data = inl(PCI_CFGMECH1_DATA_REG); + data = (data & ~mask) | (val & mask); + outl(PCI_CFGMECH1_DATA_REG, data); + outl(PCI_CFGMECH1_ADDRESS_REG, 0); +} + +static void +ix86PciSetBitsLongCFG2(PCITAG Tag, int reg, CARD32 mask, CARD32 val) +{ + CARD32 addr, data = 0; + CARD8 enable, forward; + +#ifdef DEBUGPCI + ErrorF("ix86PciSetBitsLong 0x%lx, %d\n", Tag, reg); +#endif + + forward = PCI_FORWARD_FROM_TAG(Tag); + enable = PCI_ENABLE_FROM_TAG(Tag); + addr = PCI_ADDR_FROM_TAG_CFG2(Tag,reg); + + outb(PCI_CFGMECH2_ENABLE_REG, enable); + outb(PCI_CFGMECH2_FORWARD_REG, forward); + data = inl((CARD16)addr); + data = (data & ~mask) | (val & mask); + outl((CARD16)addr, data); + outb(PCI_CFGMECH2_ENABLE_REG, 0); + outb(PCI_CFGMECH2_FORWARD_REG, 0); +} + +void +ix86PciInit() +{ + /* Initialize pciBusInfo[] array and function pointers */ + pciNumBuses = 1; + pciBusInfo[0] = &ix86Pci0; + pciFindFirstFP = pciGenFindFirst; + pciFindNextFP = pciGenFindNext; + + /* Make sure that there is a PCI bus present. */ + ix86PciSelectCfgmech(); + if (ix86Pci0.configMech == PCI_CFG_MECH_UNKNOWN) { + pciNumBuses = 0; + pciBusInfo[0] = NULL; + } +} + +#ifdef ARCH_PCI_HOST_BRIDGE + +/* + * A small table of host bridges that limit the number of PCI buses to less + * than the maximum of 256. + */ +static struct { + CARD32 devid; + int maxpcibus; +} host_bridges[] = { + { DEVID(ALI_2, M1541), 128}, + { DEVID(VIA, APOLLOVP1), 64}, + { DEVID(VIA, APOLLOPRO133X), 64}, + { DEVID(INTEL, 430HX_BRIDGE), 16}, + { DEVID(INTEL, 440BX_BRIDGE), 32}, +}; +#define NUM_BRIDGES (sizeof(host_bridges) / sizeof(host_bridges[0])) + +void ARCH_PCI_HOST_BRIDGE(pciConfigPtr pPCI) +{ + int i; + + for (i = 0; i < NUM_BRIDGES; i++) { + if (pPCI->pci_device_vendor == host_bridges[i].devid) { + pciMaxBusNum = host_bridges[i].maxpcibus; + break; + } + } +} + +#endif /* ARCH_PCI_HOST_BRIDGE */ diff --git a/hw/xfree86/os-support/bus/linuxPci.c b/hw/xfree86/os-support/bus/linuxPci.c new file mode 100644 index 000000000..76194802f --- /dev/null +++ b/hw/xfree86/os-support/bus/linuxPci.c @@ -0,0 +1,584 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/linuxPci.c,v 1.10 2002/11/17 18:42:01 alanh 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. + */ + +#include <stdio.h> +#include "compiler.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "Pci.h" + +/* + * linux platform specific PCI access functions -- using /proc/bus/pci + * needs kernel version 2.2.x + */ +static CARD32 linuxPciCfgRead(PCITAG tag, int off); +static void linuxPciCfgWrite(PCITAG, int off, CARD32 val); +static void linuxPciCfgSetBits(PCITAG tag, int off, CARD32 mask, CARD32 bits); + +static pciBusFuncs_t linuxFuncs0 = { +/* pciReadLong */ linuxPciCfgRead, +/* pciWriteLong */ linuxPciCfgWrite, +/* pciSetBitsLong */ linuxPciCfgSetBits, +/* pciAddrHostToBus */ pciAddrNOOP, +/* pciAddrBusToHost */ pciAddrNOOP +}; + +static pciBusInfo_t linuxPci0 = { +/* configMech */ PCI_CFG_MECH_OTHER, +/* numDevices */ 32, +/* secondary */ FALSE, +/* primary_bus */ 0, +#ifdef PowerMAX_OS +/* ppc_io_base */ 0, +/* ppc_io_size */ 0, +#endif +/* funcs */ &linuxFuncs0, +/* pciBusPriv */ NULL, +/* bridge */ NULL +}; + +void +linuxPciInit() +{ + struct stat st; + if ((xf86Info.pciFlags == PCIForceNone) || + (-1 == stat("/proc/bus/pci", &st))) { + /* when using this as default for all linux architectures, + we'll need a fallback for 2.0 kernels here */ + return; + } + pciNumBuses = 1; + pciBusInfo[0] = &linuxPci0; + pciFindFirstFP = pciGenFindFirst; + pciFindNextFP = pciGenFindNext; +} + +static int +linuxPciOpenFile(PCITAG tag) +{ + static int lbus,ldev,lfunc,fd = -1; + int bus, dev, func; + char file[32]; + + bus = PCI_BUS_FROM_TAG(tag); + dev = PCI_DEV_FROM_TAG(tag); + func = PCI_FUNC_FROM_TAG(tag); + if (fd == -1 || bus != lbus || dev != ldev || func != lfunc) { + if (fd != -1) + close(fd); + if (bus < 256) + sprintf(file, "/proc/bus/pci/%02x/%02x.%1x", + bus, dev, func); + else + sprintf(file, "/proc/bus/pci/%04x/%02x.%1x", + bus, dev, func); + fd = open(file,O_RDWR); + lbus = bus; + ldev = dev; + lfunc = func; + } + return fd; +} + +static CARD32 +linuxPciCfgRead(PCITAG tag, int off) +{ + int fd; + CARD32 val = 0xffffffff; + + if (-1 != (fd = linuxPciOpenFile(tag))) { + lseek(fd,off,SEEK_SET); + read(fd,&val,4); + } + return PCI_CPU(val); +} + +static void +linuxPciCfgWrite(PCITAG tag, int off, CARD32 val) +{ + int fd; + + if (-1 != (fd = linuxPciOpenFile(tag))) { + lseek(fd,off,SEEK_SET); + val = PCI_CPU(val); + write(fd,&val,4); + } +} + +static void +linuxPciCfgSetBits(PCITAG tag, int off, CARD32 mask, CARD32 bits) +{ + int fd; + CARD32 val = 0xffffffff; + + if (-1 != (fd = linuxPciOpenFile(tag))) { + lseek(fd,off,SEEK_SET); + read(fd,&val,4); + val = PCI_CPU(val); + val = (val & ~mask) | (bits & mask); + val = PCI_CPU(val); + lseek(fd,off,SEEK_SET); + write(fd,&val,4); + } +} + +#ifndef INCLUDE_XF86_NO_DOMAIN + +/* + * Compiling the following simply requires the presence of <linux/pci.c>. + * Actually running this is another matter altogether... + * + * This scheme requires that the kernel allow mmap()'ing of a host bridge's I/O + * and memory spaces through its /proc/bus/pci/BUS/DFN entry. Which one is + * determined by a prior ioctl(). + * + * For the sparc64 port, this means 2.4.12 or later. For ppc, this + * functionality is almost, but not quite there yet. Alpha and other kernel + * ports to multi-domain architectures still need to implement this. + * + * This scheme is also predicated on the use of an IOADDRESS compatible type to + * designate I/O addresses. Although IOADDRESS is defined as an unsigned + * integral type, it is actually the virtual address of, i.e. a pointer to, the + * I/O port to access. And so, the inX/outX macros in "compiler.h" need to be + * #define'd appropriately (as is done on SPARC's). + * + * Another requirement to port this scheme to another multi-domain architecture + * is to add the appropriate entries in the pciControllerSizes array below. + * + * TO DO: Address the deleterious reaction some host bridges have to master + * aborts. This is already done for secondary PCI buses, but not yet + * for accesses to primary buses (except for the SPARC port, where + * master aborts are avoided during PCI scans). + */ + +#include <linux/pci.h> + +#ifndef PCIIOC_BASE /* Ioctls for /proc/bus/pci/X/Y nodes. */ +#define PCIIOC_BASE ('P' << 24 | 'C' << 16 | 'I' << 8) + +/* Get controller for PCI device. */ +#define PCIIOC_CONTROLLER (PCIIOC_BASE | 0x00) +/* Set mmap state to I/O space. */ +#define PCIIOC_MMAP_IS_IO (PCIIOC_BASE | 0x01) +/* Set mmap state to MEM space. */ +#define PCIIOC_MMAP_IS_MEM (PCIIOC_BASE | 0x02) +/* Enable/disable write-combining. */ +#define PCIIOC_WRITE_COMBINE (PCIIOC_BASE | 0x03) + +#endif + +/* This probably shouldn't be Linux-specific */ +static pciConfigPtr +xf86GetPciHostConfigFromTag(PCITAG Tag) +{ + int bus = PCI_BUS_FROM_TAG(Tag); + pciBusInfo_t *pBusInfo; + + while ((bus < pciNumBuses) && (pBusInfo = pciBusInfo[bus])) { + if (bus == pBusInfo->primary_bus) + return pBusInfo->bridge; + bus = pBusInfo->primary_bus; + } + + return NULL; /* Bad data */ +} + +/* + * This is ugly, but until I can extract this information from the kernel, + * it'll have to do. The default I/O space size is 64K, and 4G for memory. + * Anything else needs to go in this table. (PowerPC folk take note.) + * + * Note that Linux/SPARC userland is 32-bit, so 4G overflows to zero here. + * + * Please keep this table in ascending vendor/device order. + */ +static struct pciSizes { + unsigned short vendor, device; + unsigned long io_size, mem_size; +} pciControllerSizes[] = { + { + PCI_VENDOR_SUN, PCI_CHIP_PSYCHO, + 1U << 16, 1U << 31 + }, + { + PCI_VENDOR_SUN, PCI_CHIP_SCHIZO, + 1U << 24, 1U << 31 /* ??? */ + }, + { + PCI_VENDOR_SUN, PCI_CHIP_SABRE, + 1U << 24, (unsigned long)(1ULL << 32) + }, + { + PCI_VENDOR_SUN, PCI_CHIP_HUMMINGBIRD, + 1U << 24, (unsigned long)(1ULL << 32) + } +}; +#define NUM_SIZES (sizeof(pciControllerSizes) / sizeof(pciControllerSizes[0])) + +static unsigned long +linuxGetIOSize(PCITAG Tag) +{ + pciConfigPtr pPCI; + int i; + + /* Find host bridge */ + if ((pPCI = xf86GetPciHostConfigFromTag(Tag))) { + /* Look up vendor/device */ + for (i = 0; i < NUM_SIZES; i++) { + if (pPCI->pci_vendor > pciControllerSizes[i].vendor) + continue; + if (pPCI->pci_vendor < pciControllerSizes[i].vendor) + break; + if (pPCI->pci_device > pciControllerSizes[i].device) + continue; + if (pPCI->pci_device < pciControllerSizes[i].device) + break; + return pciControllerSizes[i].io_size; + } + } + + return 1U << 16; /* Default to 64K */ +} + +static void +linuxGetSizes(PCITAG Tag, unsigned long *io_size, unsigned long *mem_size) +{ + pciConfigPtr pPCI; + int i; + + *io_size = (1U << 16); /* Default to 64K */ + *mem_size = (unsigned long)(1ULL << 32); /* Default to 4G */ + + /* Find host bridge */ + if ((pPCI = xf86GetPciHostConfigFromTag(Tag))) { + /* Look up vendor/device */ + for (i = 0; i < NUM_SIZES; i++) { + if (pPCI->pci_vendor > pciControllerSizes[i].vendor) + continue; + if (pPCI->pci_vendor < pciControllerSizes[i].vendor) + break; + if (pPCI->pci_device > pciControllerSizes[i].device) + continue; + if (pPCI->pci_device < pciControllerSizes[i].device) + break; + *io_size = pciControllerSizes[i].io_size; + *mem_size = pciControllerSizes[i].mem_size; + break; + } + } +} + +int +xf86GetPciDomain(PCITAG Tag) +{ + pciConfigPtr pPCI; + int fd, result; + + pPCI = xf86GetPciHostConfigFromTag(Tag); + + if (pPCI && (result = PCI_DOM_FROM_BUS(pPCI->busnum))) + return result; + + if ((fd = linuxPciOpenFile(pPCI ? pPCI->tag : 0)) < 0) + return 0; + + if ((result = ioctl(fd, PCIIOC_CONTROLLER, 0)) < 0) + return 0; + + return result + 1; /* Domain 0 is reserved */ +} + +static pointer +linuxMapPci(int ScreenNum, int Flags, PCITAG Tag, + ADDRESS Base, unsigned long Size, int mmap_ioctl) +{ + do { + pciConfigPtr pPCI; + unsigned char *result; + ADDRESS realBase, Offset; + int fd, mmapflags, prot; + + xf86InitVidMem(); + + pPCI = xf86GetPciHostConfigFromTag(Tag); + + if (((fd = linuxPciOpenFile(pPCI ? pPCI->tag : 0)) < 0) || + (ioctl(fd, mmap_ioctl, 0) < 0)) + break; + +/* Note: IA-64 doesn't compile this and doesn't need to */ +#ifdef __ia64__ + +# ifndef MAP_WRITECOMBINED +# define MAP_WRITECOMBINED 0x00010000 +# endif +# ifndef MAP_NONCACHED +# define MAP_NONCACHED 0x00020000 +# endif + + if (Flags & VIDMEM_FRAMEBUFFER) + mmapflags = MAP_SHARED | MAP_WRITECOMBINED; + else + mmapflags = MAP_SHARED | MAP_NONCACHED + +#else /* !__ia64__ */ + + mmapflags = (Flags & VIDMEM_FRAMEBUFFER) / VIDMEM_FRAMEBUFFER; + + if (ioctl(fd, PCIIOC_WRITE_COMBINE, mmapflags) < 0) + break; + + mmapflags = MAP_SHARED; + +#endif /* ?__ia64__ */ + + /* Align to page boundary */ + realBase = Base & ~(getpagesize() - 1); + Offset = Base - realBase; + + if (Flags & VIDMEM_READONLY) + prot = PROT_READ; + else + prot = PROT_READ | PROT_WRITE; + + result = mmap(NULL, Size + Offset, prot, mmapflags, fd, realBase); + + if (!result || ((pointer)result == MAP_FAILED)) + FatalError("linuxMapPci() mmap failure: %s\n", strerror(errno)); + + xf86MakeNewMapping(ScreenNum, Flags, realBase, Size + Offset, result); + + return result + Offset; + } while (0); + + if (mmap_ioctl == PCIIOC_MMAP_IS_MEM) + return xf86MapVidMem(ScreenNum, Flags, Base, Size); + + return NULL; +} + +pointer +xf86MapDomainMemory(int ScreenNum, int Flags, PCITAG Tag, + ADDRESS Base, unsigned long Size) +{ + return linuxMapPci(ScreenNum, Flags, Tag, Base, Size, PCIIOC_MMAP_IS_MEM); +} + +#define MAX_DOMAINS 257 +static pointer DomainMmappedIO[MAX_DOMAINS]; + +/* This has no means of returning failure, so all errors are fatal */ +IOADDRESS +xf86MapDomainIO(int ScreenNum, int Flags, PCITAG Tag, + IOADDRESS Base, unsigned long Size) +{ + int domain = xf86GetPciDomain(Tag); + + if ((domain <= 0) || (domain >= MAX_DOMAINS)) + FatalError("xf86MapDomainIO(): domain out of range\n"); + + /* Permanently map all of I/O space */ + if (!DomainMmappedIO[domain]) { + DomainMmappedIO[domain] = linuxMapPci(ScreenNum, Flags, Tag, + 0, linuxGetIOSize(Tag), + PCIIOC_MMAP_IS_IO); + if (!DomainMmappedIO[domain]) + FatalError("xf86MapDomainIO(): mmap() failure\n"); + } + + return (IOADDRESS)DomainMmappedIO[domain] + Base; +} + +int +xf86ReadDomainMemory(PCITAG Tag, ADDRESS Base, int Len, unsigned char *Buf) +{ + unsigned char *ptr, *src; + ADDRESS offset; + unsigned long size; + int len, pagemask = getpagesize() - 1; + + /* Ensure page boundaries */ + offset = Base & ~pagemask; + size = ((Base + Len + pagemask) & ~pagemask) - offset; + + ptr = xf86MapDomainMemory(-1, VIDMEM_READONLY, Tag, offset, size); + + if (!ptr) + return -1; + + /* Using memcpy() here can hang the system */ + src = ptr + (Base - offset); + for (len = Len; len-- > 0;) + *Buf++ = *src++; + + xf86UnMapVidMem(-1, ptr, size); + + return Len; +} + +resPtr +xf86BusAccWindowsFromOS(void) +{ + pciConfigPtr *ppPCI, pPCI; + resPtr pRes = NULL; + resRange range; + unsigned long io_size, mem_size; + int domain; + + if ((ppPCI = xf86scanpci(0))) { + for (; (pPCI = *ppPCI); ppPCI++) { + if ((pPCI->pci_base_class != PCI_CLASS_BRIDGE) || + (pPCI->pci_sub_class != PCI_SUBCLASS_BRIDGE_HOST)) + continue; + + domain = xf86GetPciDomain(pPCI->tag); + linuxGetSizes(pPCI->tag, &io_size, &mem_size); + + RANGE(range, 0, (ADDRESS)(mem_size - 1), + RANGE_TYPE(ResExcMemBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + + RANGE(range, 0, (IOADDRESS)(io_size - 1), + RANGE_TYPE(ResExcIoBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + + if (domain <= 0) + break; + } + } + + return pRes; +} + +resPtr +xf86PciBusAccWindowsFromOS(void) +{ + pciConfigPtr *ppPCI, pPCI; + resPtr pRes = NULL; + resRange range; + unsigned long io_size, mem_size; + int domain; + + if ((ppPCI = xf86scanpci(0))) { + for (; (pPCI = *ppPCI); ppPCI++) { + if ((pPCI->pci_base_class != PCI_CLASS_BRIDGE) || + (pPCI->pci_sub_class != PCI_SUBCLASS_BRIDGE_HOST)) + continue; + + domain = xf86GetPciDomain(pPCI->tag); + linuxGetSizes(pPCI->tag, &io_size, &mem_size); + + RANGE(range, 0, (ADDRESS)(mem_size - 1), + RANGE_TYPE(ResExcMemBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + + RANGE(range, 0, (IOADDRESS)(io_size - 1), + RANGE_TYPE(ResExcIoBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + + if (domain <= 0) + break; + } + } + + return pRes; +} + + +resPtr +xf86AccResFromOS(resPtr pRes) +{ + pciConfigPtr *ppPCI, pPCI; + resRange range; + unsigned long io_size, mem_size; + int domain; + + if ((ppPCI = xf86scanpci(0))) { + for (; (pPCI = *ppPCI); ppPCI++) { + if ((pPCI->pci_base_class != PCI_CLASS_BRIDGE) || + (pPCI->pci_sub_class != PCI_SUBCLASS_BRIDGE_HOST)) + continue; + + domain = xf86GetPciDomain(pPCI->tag); + linuxGetSizes(pPCI->tag, &io_size, &mem_size); + + /* + * At minimum, the top and bottom resources must be claimed, so + * that resources that are (or appear to be) unallocated can be + * relocated. + */ + RANGE(range, 0x00000000u, 0x0009ffffu, + RANGE_TYPE(ResExcMemBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + RANGE(range, 0x000c0000u, 0x000effffu, + RANGE_TYPE(ResExcMemBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + RANGE(range, 0x000f0000u, 0x000fffffu, + RANGE_TYPE(ResExcMemBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + + RANGE(range, (ADDRESS)(mem_size - 1), (ADDRESS)(mem_size - 1), + RANGE_TYPE(ResExcMemBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + + RANGE(range, 0x00000000u, 0x00000000u, + RANGE_TYPE(ResExcIoBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + RANGE(range, (IOADDRESS)(io_size - 1), (IOADDRESS)(io_size - 1), + RANGE_TYPE(ResExcIoBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + + if (domain <= 0) + break; + } + } + + return pRes; +} + +#endif /* !INCLUDE_XF86_NO_DOMAIN */ diff --git a/hw/xfree86/os-support/bus/netbsdPci.c b/hw/xfree86/os-support/bus/netbsdPci.c new file mode 100644 index 000000000..637bd7021 --- /dev/null +++ b/hw/xfree86/os-support/bus/netbsdPci.c @@ -0,0 +1,127 @@ +/* + * Copyright (C) 1994-2002 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, copy, + * modify, merge, publish, distribute, sublicense, and/or sell copies + * of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE XFREE86 PROJECT BE LIABLE + * FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project + * shall not be used in advertising or otherwise to promote the sale, + * use or other dealings in this Software without prior written + * authorization from the XFree86 Project. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/netbsdPci.c,v 1.2 2002/08/27 22:07:07 tsi Exp $ */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/ioctl.h> +#include <fcntl.h> +#include <stdio.h> +#include <unistd.h> +#include <dev/pci/pciio.h> + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86OSpriv.h" + +#include "Pci.h" + +static CARD32 netbsdPciConfRead(PCITAG, int); +static void netbsdPciConfWrite(PCITAG, int, CARD32); +static void netbsdPciSetBits(PCITAG, int, CARD32, CARD32); + +static int devpci = -1; + +static pciBusFuncs_t netbsdFuncs0 = { +/* pciReadLong */ netbsdPciConfRead, +/* pciWriteLong */ netbsdPciConfWrite, +/* pciSetBitsLong */ netbsdPciSetBits, +/* pciAddrHostToBus */ pciAddrNOOP, +/* pciAddrBusToHost */ pciAddrNOOP +}; + +static pciBusInfo_t netbsdPci0 = { +/* configMech */ PCI_CFG_MECH_OTHER, +/* numDevices */ 32, +/* secondary */ FALSE, +/* primary_bus */ 0, +#ifdef PowerMAX_OS +/* io_base */ 0, +/* io_size */ 0, +#endif +/* funcs */ &netbsdFuncs0, +/* pciBusPriv */ NULL, +/* bridge */ NULL +}; + +void +netbsdPciInit() +{ + + devpci = open("/dev/pci0", O_RDWR); + if (devpci == -1) + FatalError("netbsdPciInit: can't open /dev/pci0\n"); + + pciNumBuses = 1; + pciBusInfo[0] = &netbsdPci0; + pciFindFirstFP = pciGenFindFirst; + pciFindNextFP = pciGenFindNext; +} + +static CARD32 +netbsdPciConfRead(PCITAG tag, int reg) +{ + struct pciio_bdf_cfgreg bdfr; + + bdfr.bus = PCI_BUS_FROM_TAG(tag); + bdfr.device = PCI_DEV_FROM_TAG(tag); + bdfr.function = PCI_FUNC_FROM_TAG(tag); + bdfr.cfgreg.reg = reg; + + if (ioctl(devpci, PCI_IOC_BDF_CFGREAD, &bdfr) == -1) + FatalError("netbsdPciConfRead: failed on %d/%d/%d\n", + bdfr.bus, bdfr.device, bdfr.function); + + return (bdfr.cfgreg.val); +} + +static void +netbsdPciConfWrite(PCITAG tag, int reg, CARD32 val) +{ + struct pciio_bdf_cfgreg bdfr; + + bdfr.bus = PCI_BUS_FROM_TAG(tag); + bdfr.device = PCI_DEV_FROM_TAG(tag); + bdfr.function = PCI_FUNC_FROM_TAG(tag); + bdfr.cfgreg.reg = reg; + bdfr.cfgreg.val = val; + + if (ioctl(devpci, PCI_IOC_BDF_CFGWRITE, &bdfr) == -1) + FatalError("netbsdPciConfWrite: failed on %d/%d/%d\n", + bdfr.bus, bdfr.device, bdfr.function); +} + +static void +netbsdPciSetBits(PCITAG tag, int reg, CARD32 mask, CARD32 bits) +{ + CARD32 val; + + val = netbsdPciConfRead(tag, reg); + val = (val & ~mask) | (bits & mask); + netbsdPciConfWrite(tag, reg, val); +} diff --git a/hw/xfree86/os-support/bus/ppcPci.c b/hw/xfree86/os-support/bus/ppcPci.c new file mode 100644 index 000000000..2aa98355b --- /dev/null +++ b/hw/xfree86/os-support/bus/ppcPci.c @@ -0,0 +1,212 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/ppcPci.c,v 1.9 2002/08/27 22:07:07 tsi Exp $ */ +/* + * ppcPci.c - PowerPC PCI access functions + * + * PCI driver functions supporting Motorola PowerPC platforms + * including Powerstack(RiscPC/RiscPC+), PowerStackII, MTX, and + * MVME 160x/260x/360x/460x VME boards + * + * Gary Barton + * Concurrent Computer Corporation + * garyb@gate.net + * + */ + +/* + * 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. + */ + +#include <stdio.h> +#include "compiler.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "Pci.h" + +#ifndef MAP_FAILED +#define MAP_FAILED (pointer)(-1) +#endif + +void +ppcPciInit() +{ +#if defined(PowerMAX_OS) + extern void pmaxPciInit(void); + + pmaxPciInit(); + +#else + + extern void motoppcPciInit(void); + + motoppcPciInit(); + +#endif +} + +/* + * Motorola PowerPC platform support + * + * The following code should support the MVME 1600 & 2600 VME boards + * as well as the various PowerStack and RiscPC models. All of these + * machines support PCI config mechanism #1 and use the std config + * address and data regs locations: + * cfg address reg = 0xcf8 (PCI I/O) + * cfg data reg = 0xcfc (PCI I/O) + * + * The moto machines do have different address maps on either side + * of the PCI-host bridge though. + */ +static ADDRESS motoppcBusAddrToHostAddr(PCITAG, PciAddrType, ADDRESS); +static ADDRESS motoppcHostAddrToBusAddr(PCITAG, PciAddrType, ADDRESS); + +static pciBusFuncs_t motoppcFuncs0 = { +/* pciReadLong */ pciCfgMech1Read, +/* pciWriteLong */ pciCfgMech1Write, +/* pciSetBitsLong */ pciCfgMech1SetBits, +/* pciAddrHostToBus */ motoppcHostAddrToBusAddr, +/* pciAddrBusToHost */ motoppcBusAddrToHostAddr +}; + +static pciBusInfo_t motoppcPci0 = { +/* configMech */ PCI_CFG_MECH_1, +/* numDevices */ 32, +/* secondary */ FALSE, +/* primary_bus */ 0, +#ifdef PowerMAX_OS +/* ppc_io_base */ 0x80000000, +/* ppc_io_size */ 64 * 1024, +#endif +/* funcs */ &motoppcFuncs0, +/* pciBusPriv */ NULL, +/* bridge */ NULL +}; + +extern volatile unsigned char *ioBase; + +void +motoppcPciInit() +{ + pciNumBuses = 1; + pciBusInfo[0] = &motoppcPci0; + pciFindFirstFP = pciGenFindFirst; + pciFindNextFP = pciGenFindNext; + + if (ioBase == MAP_FAILED) { + ppcPciIoMap(0); /* Make inb/outb et al work for pci0 and its secondaries */ + + if (ioBase == MAP_FAILED) { + FatalError("motoppcPciInit: Cannot map pci0 I/O segment!!!\n"); + /*NOTREACHED*/ + } + } +} + +extern unsigned long motoPciMemBase = 0; + +#if defined(Lynx) && defined(__powerpc__) +extern unsigned long motoPciMemLen = 0x40000000; +#else +extern unsigned long motoPciMemLen = 0x3f000000; +#endif + +extern unsigned long motoPciMemBaseCPU = 0xc0000000; + +static ADDRESS +motoppcBusAddrToHostAddr(PCITAG tag, PciAddrType type, ADDRESS addr) +{ + unsigned long addr_l = (unsigned long)addr; + + if (type == PCI_MEM) { + if (addr_l >= motoPciMemBase && addr_l < motoPciMemLen) + /* + * PCI memory space addresses [0-0x3effffff] are + * are seen at [0xc0000000,0xfeffffff] on moto host + */ + return((ADDRESS)((motoPciMemBaseCPU - motoPciMemBase) + addr_l)); + + else if (addr_l >= 0x80000000) + /* + * Moto host memory [0,0x7fffffff] is seen at + * [0x80000000,0xffffffff] on PCI bus + */ + return((ADDRESS)(addr_l & 0x7fffffff)); + else + FatalError("motoppcBusAddrToHostAddr: PCI addr 0x%x is not accessible to host!!!\n", + addr_l); + } else + return addr; + + /*NOTREACHED*/ +} + +static ADDRESS +motoppcHostAddrToBusAddr(PCITAG tag, PciAddrType type, ADDRESS addr) +{ + unsigned long addr_l = (unsigned long)addr; + + if (type == PCI_MEM) { + if (addr_l < 0x80000000) + /* + * Moto host memory [0,0x7fffffff] is seen at + * [0x80000000,0xffffffff] on PCI bus + */ + return((ADDRESS)(0x80000000 | addr_l)); + + else if (addr_l >= motoPciMemBaseCPU && addr_l < motoPciMemBaseCPU + motoPciMemLen) + /* + * PCI memory space addresses [0-0x3effffff] are + * are seen at [0xc0000000,0xfeffffff] on moto host + */ + return((ADDRESS)(addr_l - (motoPciMemBaseCPU - motoPciMemBase))); + + else + FatalError("motoppcHostAddrToBusAddr: Host addr 0x%x is not accessible to PCI!!!\n", + addr_l); + } else + return addr; + + /*NOTREACHED*/ +} diff --git a/hw/xfree86/os-support/bus/sparcPci.c b/hw/xfree86/os-support/bus/sparcPci.c new file mode 100644 index 000000000..24bbec44c --- /dev/null +++ b/hw/xfree86/os-support/bus/sparcPci.c @@ -0,0 +1,1048 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/sparcPci.c,v 1.12 2003/01/02 18:11:32 tsi Exp $ */ +/* + * Copyright (C) 2001 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "Pci.h" +#include "xf86sbusBus.h" + +#if defined(sun) + +extern char *apertureDevName; +static int apertureFd = -1; + +/* + * A version of xf86MapVidMem() that allows for 64-bit displacements (but not + * sizes). Areas thus mapped can be unmapped by xf86UnMapVidMem(). + */ +static pointer +sparcMapAperture(int iScreen, int Flags, + unsigned long long Base, unsigned long Size) +{ + pointer result; + static int lastFlags = 0; + + /* Assume both Base & Size are multiples of the page size */ + + if ((apertureFd < 0) || (Flags != lastFlags)) { + if (apertureFd >= 0) + close(apertureFd); + lastFlags = Flags; + apertureFd = open(apertureDevName, + (Flags & VIDMEM_READONLY) ? O_RDONLY : O_RDWR); + if (apertureFd < 0) + FatalError("sparcMapAperture: open failure: %s\n", + strerror(errno)); + } + + result = mmap(NULL, Size, + (Flags & VIDMEM_READONLY) ? + PROT_READ : (PROT_READ | PROT_WRITE), + MAP_SHARED, apertureFd, (off_t)Base); + + if (result == MAP_FAILED) + FatalError("sparcMapAperture: mmap failure: %s\n", strerror(errno)); + + return result; +} + +/* + * Platform-specific bus privates. + */ +typedef struct _sparcDomainRec { + unsigned long long io_addr, io_size; + unsigned long long mem_addr, mem_size; + pointer pci, io; + int bus_min, bus_max; + unsigned char dfn_mask[256 / 8]; +} sparcDomainRec, *sparcDomainPtr; + +#define SetBitInMap(bit, map) \ + do { \ + int _bit = (bit); \ + (map)[_bit >> 3] |= 1 << (_bit & 7); \ + } while (0) + +#define IsBitSetInMap(bit, map) \ + ((map)[(bit) >> 3] & (1 << ((bit) & 7))) + +/* + * Domain 0 is reserved for the one that represents the system as a whole, i.e. + * the one without any resource relocations. + */ +#define MAX_DOMAINS (MAX_PCI_BUSES / 256) +static sparcDomainPtr xf86DomainInfo[MAX_DOMAINS]; +static int pciNumDomains = 1; + +/* Variables that are assigned this must be declared volatile */ +#define PciReg(base, tag, off, type) \ + *(volatile type *)(pointer)((char *)(base) + \ + (PCI_TAG_NO_DOMAIN(tag) | (off))) + +/* Generic SPARC PCI access functions */ +static CARD32 +sparcPciCfgRead32(PCITAG tag, int off) +{ + pciBusInfo_t *pBusInfo; + sparcDomainPtr pDomain; + volatile CARD32 result = (CARD32)(-1); /* Must be volatile */ + int bus; + + if ((off >= 0) && (off <= 252) && !(off & 3) && + ((bus = PCI_BUS_FROM_TAG(tag)) < pciNumBuses) && + (pBusInfo = pciBusInfo[bus]) && (pDomain = pBusInfo->pciBusPriv) && + (bus >= pDomain->bus_min) && (bus < pDomain->bus_max) && + ((bus > pDomain->bus_min) || + IsBitSetInMap(PCI_DFN_FROM_TAG(tag), pDomain->dfn_mask))) { + result = PciReg(pDomain->pci, tag, off, CARD32); + + result = PCI_CPU(result); + } + + return result; +} + +static void +sparcPciCfgWrite32(PCITAG tag, int off, CARD32 val) +{ + pciBusInfo_t *pBusInfo; + sparcDomainPtr pDomain; + int bus; + + if ((off < 0) || (off > 252) || (off & 3) || + ((bus = PCI_BUS_FROM_TAG(tag)) >= pciNumBuses) || + !(pBusInfo = pciBusInfo[bus]) || !(pDomain = pBusInfo->pciBusPriv) || + (bus < pDomain->bus_min) || (bus >= pDomain->bus_max) || + ((bus == pDomain->bus_min) && + !IsBitSetInMap(PCI_DFN_FROM_TAG(tag), pDomain->dfn_mask))) + return; + + val = PCI_CPU(val); + PciReg(pDomain->pci, tag, off, CARD32) = val; +} + +static void +sparcPciCfgSetBits32(PCITAG tag, int off, CARD32 mask, CARD32 bits) +{ + CARD32 PciVal; + + PciVal = sparcPciCfgRead32(tag, off); + PciVal &= ~mask; + PciVal |= bits; + sparcPciCfgWrite32(tag, off, PciVal); +} + +static pciBusFuncs_t sparcPCIFunctions = +{ + sparcPciCfgRead32, + sparcPciCfgWrite32, + sparcPciCfgSetBits32, + pciAddrNOOP, + pciAddrNOOP +}; + +/* + * Sabre-specific versions of the above because of its peculiar access size + * requirements. + */ +static CARD32 +sabrePciCfgRead32(PCITAG tag, int off) +{ + pciBusInfo_t *pBusInfo; + sparcDomainPtr pDomain; + volatile CARD32 result; /* Must be volatile */ + int bus; + + if (PCI_BDEV_FROM_TAG(tag)) + return sparcPciCfgRead32(tag, off); + + if (PCI_FUNC_FROM_TAG(tag) || (off < 0) || (off > 252) || (off & 3) || + ((bus = PCI_BUS_FROM_TAG(tag)) >= pciNumBuses) || + !(pBusInfo = pciBusInfo[bus]) || !(pDomain = pBusInfo->pciBusPriv) || + (bus != pDomain->bus_min)) + return (CARD32)(-1); + + if (off < 8) { + result = (PciReg(pDomain->pci, tag, off, CARD16) << 16) | + PciReg(pDomain->pci, tag, off + 2, CARD16); + return PCI_CPU(result); + } + + result = (PciReg(pDomain->pci, tag, off + 3, CARD8) << 24) | + (PciReg(pDomain->pci, tag, off + 2, CARD8) << 16) | + (PciReg(pDomain->pci, tag, off + 1, CARD8) << 8) | + (PciReg(pDomain->pci, tag, off , CARD8) ); + return result; +} + +static void +sabrePciCfgWrite32(PCITAG tag, int off, CARD32 val) +{ + pciBusInfo_t *pBusInfo; + sparcDomainPtr pDomain; + int bus; + + if (PCI_BDEV_FROM_TAG(tag)) + sparcPciCfgWrite32(tag, off, val); + else if (!PCI_FUNC_FROM_TAG(tag) && + (off >= 0) && (off <= 252) && !(off & 3) && + ((bus = PCI_BUS_FROM_TAG(tag)) < pciNumBuses) && + (pBusInfo = pciBusInfo[bus]) && + (pDomain = pBusInfo->pciBusPriv) && + (bus == pDomain->bus_min)) { + if (off < 8) { + val = PCI_CPU(val); + PciReg(pDomain->pci, tag, off , CARD16) = val >> 16; + PciReg(pDomain->pci, tag, off + 2, CARD16) = val; + } else { + PciReg(pDomain->pci, tag, off , CARD8) = val; + PciReg(pDomain->pci, tag, off + 1, CARD8) = val >> 8; + PciReg(pDomain->pci, tag, off + 2, CARD8) = val >> 16; + PciReg(pDomain->pci, tag, off + 3, CARD8) = val >> 24; + } + } +} + +static void +sabrePciCfgSetBits32(PCITAG tag, int off, CARD32 mask, CARD32 bits) +{ + CARD32 PciVal; + + PciVal = sabrePciCfgRead32(tag, off); + PciVal &= ~mask; + PciVal |= bits; + sabrePciCfgWrite32(tag, off, PciVal); +} + +static pciBusFuncs_t sabrePCIFunctions = +{ + sabrePciCfgRead32, + sabrePciCfgWrite32, + sabrePciCfgSetBits32, + pciAddrNOOP, + pciAddrNOOP +}; + +static int pagemask; + +/* Scan PROM for all PCI host bridges in the system */ +void +sparcPciInit(void) +{ + int node, node2; + + if (!xf86LinearVidMem()) + return; + + apertureFd = open(apertureDevName, O_RDWR); + if (apertureFd < 0) { + xf86Msg(X_ERROR, + "sparcPciInit: open failure: %s\n", strerror(errno)); + return; + } + + sparcPromInit(); + pagemask = xf86getpagesize() - 1; + + for (node = promGetChild(promRootNode); + node; + node = promGetSibling(node)) { + unsigned long long pci_addr; + sparcDomainRec domain; + sparcDomainPtr pDomain; + pciBusFuncs_p pFunctions; + char *prop_val; + int prop_len, bus; + + prop_val = promGetProperty("name", &prop_len); + /* Some PROMs include the trailing null; some don't */ + if (!prop_val || (prop_len < 3) || (prop_len > 4) || + strcmp(prop_val, "pci")) + continue; + + prop_val = promGetProperty("model", &prop_len); + if (!prop_val || (prop_len <= 0)) { + prop_val = promGetProperty("compatible", &prop_len); + if (!prop_val || (prop_len <= 0)) + continue; + } + + pFunctions = &sparcPCIFunctions; + (void)memset(&domain, 0, sizeof(domain)); + + if (!strncmp("SUNW,sabre", prop_val, prop_len) || + !strncmp("pci108e,a000", prop_val, prop_len) || + !strncmp("pci108e,a001", prop_val, prop_len)) { + /* + * There can only be one "Sabre" bridge in a system. It provides + * PCI configuration space, a 24-bit I/O space and a 32-bit memory + * space, all three of which are at fixed physical CPU addresses. + */ + static Bool sabre_seen = FALSE; + + xf86Msg(X_INFO, + "Sabre or Hummingbird PCI host bridge found (\"%s\")\n", + prop_val); + + /* There can only be one Sabre */ + if (sabre_seen) + continue; + sabre_seen = TRUE; + + /* Get "bus-range" property */ + prop_val = promGetProperty("bus-range", &prop_len); + if (!prop_val || (prop_len != 8) || + (((unsigned int *)prop_val)[0]) || + (((unsigned int *)prop_val)[1] >= 256)) + continue; + + pci_addr = 0x01fe01000000ull; + domain.io_addr = 0x01fe02000000ull; + domain.io_size = 0x000001000000ull; + domain.mem_addr = 0x01ff00000000ull; + domain.mem_size = 0x000100000000ull; + domain.bus_min = 0; /* Always */ + domain.bus_max = ((int *)prop_val)[1]; + + pFunctions = &sabrePCIFunctions; + } else + if (!strncmp("SUNW,psycho", prop_val, prop_len) || + !strncmp("pci108e,8000", prop_val, prop_len)) { + /* + * A "Psycho" host bridge provides two PCI interfaces, each with + * its own 16-bit I/O and 31-bit memory spaces. Both share the + * same PCI configuration space. Here, they are assigned separate + * domain numbers to prevent unintentional I/O and/or memory + * resource conflicts. + */ + xf86Msg(X_INFO, + "Psycho PCI host bridge found (\"%s\")\n", prop_val); + + /* Get "bus-range" property */ + prop_val = promGetProperty("bus-range", &prop_len); + if (!prop_val || (prop_len != 8) || + (((unsigned int *)prop_val)[1] >= 256) || + (((unsigned int *)prop_val)[0] > ((unsigned int *)prop_val)[1])) + continue; + + domain.bus_min = ((int *)prop_val)[0]; + domain.bus_max = ((int *)prop_val)[1]; + + /* Get "ranges" property */ + prop_val = promGetProperty("ranges", &prop_len); + if (!prop_val || (prop_len != 112) || + prop_val[0] || (prop_val[28] != 0x01u) || + (prop_val[56] != 0x02u) || (prop_val[84] != 0x03u) || + (((unsigned int *)prop_val)[4] != 0x01000000u) || + ((unsigned int *)prop_val)[5] || + ((unsigned int *)prop_val)[12] || + (((unsigned int *)prop_val)[13] != 0x00010000u) || + ((unsigned int *)prop_val)[19] || + (((unsigned int *)prop_val)[20] != 0x80000000u) || + ((((unsigned int *)prop_val)[11] & ~0x00010000u) != + 0x02000000u) || + (((unsigned int *)prop_val)[18] & ~0x80000000u) || + (((unsigned int *)prop_val)[3] != + ((unsigned int *)prop_val)[10]) || + (((unsigned int *)prop_val)[17] != + ((unsigned int *)prop_val)[24]) || + (((unsigned int *)prop_val)[18] != + ((unsigned int *)prop_val)[25]) || + (((unsigned int *)prop_val)[19] != + ((unsigned int *)prop_val)[26]) || + (((unsigned int *)prop_val)[20] != + ((unsigned int *)prop_val)[27])) + continue; + + /* Use memcpy() to avoid alignment issues */ + (void)memcpy(&pci_addr, prop_val + 12, + sizeof(pci_addr)); + (void)memcpy(&domain.io_addr, prop_val + 40, + sizeof(domain.io_addr)); + (void)memcpy(&domain.mem_addr, prop_val + 68, + sizeof(domain.mem_addr)); + + domain.io_size = 0x000000010000ull; + domain.mem_size = 0x000080000000ull; + } else + if (!strncmp("SUNW,schizo", prop_val, prop_len) || + !strncmp("pci108e,8001", prop_val, prop_len)) { + /* + * I have no docs on the "Schizo", but judging from the Linux + * kernel, it also provides two PCI domains. Each PCI + * configuration space is the usual 16M in size, followed by a + * variable-length I/O space. Each domain also provides a + * variable-length memory space. The kernel seems to think the I/O + * spaces are 16M long, and the memory spaces, 2G, but these + * assumptions are actually only present in source code comments. + * Sun has, however, confirmed to me the validity of these + * assumptions. + */ + volatile unsigned long long mem_match, mem_mask, io_match, io_mask; + unsigned long Offset; + pointer pSchizo; + + xf86Msg(X_INFO, + "Schizo PCI host bridge found (\"%s\")\n", prop_val); + + /* Get "bus-range" property */ + prop_val = promGetProperty("bus-range", &prop_len); + if (!prop_val || (prop_len != 8) || + (((unsigned int *)prop_val)[1] >= 256) || + (((unsigned int *)prop_val)[0] > ((unsigned int *)prop_val)[1])) + continue; + + domain.bus_min = ((int *)prop_val)[0]; + domain.bus_max = ((int *)prop_val)[1]; + + /* Get "reg" property */ + prop_val = promGetProperty("reg", &prop_len); + if (!prop_val || (prop_len != 48)) + continue; + + /* Temporarily map some of Schizo's registers */ + pSchizo = sparcMapAperture(-1, VIDMEM_MMIO, + ((unsigned long long *)prop_val)[2] - 0x000000010000ull, + 0x00010000ul); + + /* Determine where PCI config, I/O and memory spaces reside */ + if ((((unsigned long long *)prop_val)[0] & 0x000000700000ull) == + 0x000000600000ull) + Offset = 0x0040; + else + Offset = 0x0060; + + mem_match = PciReg(pSchizo, 0, Offset, unsigned long long); + mem_mask = PciReg(pSchizo, 0, Offset + 8, unsigned long long); + io_match = PciReg(pSchizo, 0, Offset + 16, unsigned long long); + io_mask = PciReg(pSchizo, 0, Offset + 24, unsigned long long); + + /* Unmap Schizo registers */ + xf86UnMapVidMem(-1, pSchizo, 0x00010000ul); + + /* Calculate sizes */ + mem_mask = (((mem_mask - 1) ^ mem_mask) >> 1) + 1; + io_mask = (((io_mask - 1) ^ io_mask ) >> 1) + 1; + + if (io_mask <= 0x000001000000ull) /* Nothing left for I/O */ + continue; + + domain.mem_addr = mem_match & ~0x8000000000000000ull; + domain.mem_size = mem_mask; + pci_addr = io_match & ~0x8000000000000000ull; + domain.io_addr = pci_addr + 0x0000000001000000ull; + domain.io_size = io_mask - 0x0000000001000000ull; + } else { + xf86Msg(X_WARNING, "Unknown PCI host bridge: \"%s\"\n", prop_val); + continue; + } + + /* Only map as much PCI configuration as we need */ + domain.pci = (char *)sparcMapAperture(-1, VIDMEM_MMIO, + pci_addr + PCI_MAKE_TAG(domain.bus_min, 0, 0), + PCI_MAKE_TAG(domain.bus_max - domain.bus_min + 1, 0, 0)) - + PCI_MAKE_TAG(domain.bus_min, 0, 0); + + /* Allocate a domain record */ + pDomain = xnfalloc(sizeof(sparcDomainRec)); + *pDomain = domain; + + /* + * Allocate and prime pciBusInfo records. These are allocated one at a + * time because those for empty buses are eventually released. + */ + bus = pDomain->bus_min = + PCI_MAKE_BUS(pciNumDomains, domain.bus_min); + pciNumBuses = pDomain->bus_max = + PCI_MAKE_BUS(pciNumDomains, domain.bus_max) + 1; + + pciBusInfo[bus] = xnfcalloc(1, sizeof(pciBusInfo_t)); + pciBusInfo[bus]->configMech = PCI_CFG_MECH_OTHER; + pciBusInfo[bus]->numDevices = 32; + pciBusInfo[bus]->funcs = pFunctions; + pciBusInfo[bus]->pciBusPriv = pDomain; + while (++bus < pciNumBuses) { + pciBusInfo[bus] = xnfalloc(sizeof(pciBusInfo_t)); + *(pciBusInfo[bus]) = *(pciBusInfo[bus - 1]); + pciBusInfo[bus]->funcs = &sparcPCIFunctions; + } + + /* Next domain, please... */ + xf86DomainInfo[pciNumDomains++] = pDomain; + + /* + * OK, enough of the straight-forward stuff. Time to deal with some + * brokenness... + * + * The PCI specs require that when a bus transaction remains unclaimed + * for too long, the master entity on that bus is to cancel the + * transaction it issued or passed on with a master abort. Two + * outcomes are possible: + * + * - the master abort can be treated as an error that is propogated + * back through the bus tree to the entity that ultimately originated + * the transaction; or + * - the transaction can be allowed to complete normally, which means + * that writes are ignored and reads return all ones. + * + * In the first case, if the CPU happens to be at the tail end of the + * tree path through one of its host bridges, it will be told there is + * a hardware mal-function, despite being generated by software. + * + * For a software function (be it firmware, OS or userland application) + * to determine how a PCI bus tree is populated, it must be able to + * detect when master aborts occur. Obviously, PCI discovery is much + * simpler when master aborts are allowed to complete normally. + * + * Unfortunately, a number of non-Intel PCI implementations have chosen + * to treat master aborts as severe errors. The net effect is to + * cripple PCI discovery algorithms in userland. + * + * On SPARCs, master aborts cause a number of different behaviours, + * including delivering a signal to the userland application, rebooting + * the system, "dropping down" to firmware, or, worst of all, bus + * lockouts. Even in the first case, the SIGBUS signal that is + * eventually generated isn't delivered in a timely enough fashion to + * allow an application to reliably detect the master abort that + * ultimately caused it. + * + * This can be somewhat mitigated. On all architectures, master aborts + * that occur on secondary buses can be forced to complete normally + * because the PCI-to-PCI bridges that serve them are governed by an + * industry-wide specification. (This is just another way of saying + * that whatever justification there might be for erroring out master + * aborts is deemed by the industry as insufficient to generate more + * PCI non-compliance than there already is...) + * + * This leaves us with master aborts that occur on primary buses. + * There is no specification for host-to-PCI bridges. Bridges used in + * SPARCs can be told to ignore all PCI errors, but not specifically + * master aborts. Not only is this too coarse-grained, but + * master-aborted read transactions on the primary bus end up returning + * garbage rather than all ones. + * + * I have elected to work around this the only way I can think of doing + * so right now. The following scans an additional PROM level and + * builds a device/function map for the primary bus. I can only hope + * this PROM information represents all devices on the primary bus, + * rather than only a subset of them. + * + * Master aborts are useful in other ways too, that are not addressed + * here. These include determining whether or not a domain provides + * VGA, or if a PCI device actually implements PCI disablement. + * + * --- TSI @ UQV 2001.09.19 + */ + for (node2 = promGetChild(node); + node2; + node2 = promGetSibling(node2)) { + /* Get "reg" property */ + prop_val = promGetProperty("reg", &prop_len); + if (!prop_val || (prop_len % 20)) + continue; + + /* + * It's unnecessary to scan the entire "reg" property, but I'll do + * so anyway. + */ + prop_len /= 20; + for (; prop_len--; prop_val += 20) + SetBitInMap(PCI_DFN_FROM_TAG(*(PCITAG *)prop_val), + pDomain->dfn_mask); + } + + /* Assume the host bridge is device 0, function 0 on its bus */ + SetBitInMap(0, pDomain->dfn_mask); + } + + sparcPromClose(); + + close(apertureFd); + apertureFd = -1; +} + +#ifndef INCLUDE_XF86_NO_DOMAIN + +int +xf86GetPciDomain(PCITAG Tag) +{ + return PCI_DOM_FROM_TAG(Tag); +} + +pointer +xf86MapDomainMemory(int ScreenNum, int Flags, PCITAG Tag, + ADDRESS Base, unsigned long Size) +{ + sparcDomainPtr pDomain; + pointer result; + int domain = PCI_DOM_FROM_TAG(Tag); + + if ((domain <= 0) || (domain >= pciNumDomains) || + !(pDomain = xf86DomainInfo[domain]) || + (((unsigned long long)Base + (unsigned long long)Size) > + pDomain->mem_size)) + FatalError("xf86MapDomainMemory() called with invalid parameters.\n"); + + result = sparcMapAperture(ScreenNum, Flags, pDomain->mem_addr + Base, Size); + + if (apertureFd >= 0) { + close(apertureFd); + apertureFd = -1; + } + + return result; +} + +IOADDRESS +xf86MapDomainIO(int ScreenNum, int Flags, PCITAG Tag, + IOADDRESS Base, unsigned long Size) +{ + sparcDomainPtr pDomain; + int domain = PCI_DOM_FROM_TAG(Tag); + + if ((domain <= 0) || (domain >= pciNumDomains) || + !(pDomain = xf86DomainInfo[domain]) || + (((unsigned long long)Base + (unsigned long long)Size) > + pDomain->io_size)) + FatalError("xf86MapDomainIO() called with invalid parameters.\n"); + + /* Permanently map all of I/O space */ + if (!pDomain->io) { + pDomain->io = sparcMapAperture(ScreenNum, Flags, + pDomain->io_addr, pDomain->io_size); + + if (apertureFd >= 0) { + close(apertureFd); + apertureFd = -1; + } + } + + return (IOADDRESS)pDomain->io + Base; +} + +int +xf86ReadDomainMemory(PCITAG Tag, ADDRESS Base, int Len, unsigned char *Buf) +{ + unsigned char *ptr, *src; + ADDRESS offset; + unsigned long size; + int len; + + /* Ensure page boundaries */ + offset = Base & ~pagemask; + size = ((Base + Len + pagemask) & ~pagemask) - offset; + + ptr = xf86MapDomainMemory(-1, VIDMEM_READONLY, Tag, offset, size); + + /* Using memcpy() here hangs the system */ + src = ptr + (Base - offset); + for (len = Len; len-- > 0;) + *Buf++ = *src++; + + xf86UnMapVidMem(-1, ptr, size); + + return Len; +} + +resPtr +xf86BusAccWindowsFromOS(void) +{ + sparcDomainPtr pDomain; + resPtr pRes = NULL; + resRange range; + int domain; + + for (domain = 1; domain < pciNumDomains; domain++) { + if (!(pDomain = xf86DomainInfo[domain])) + continue; + + RANGE(range, 0, pDomain->mem_size - 1, + RANGE_TYPE(ResExcMemBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + + RANGE(range, 0, pDomain->io_size - 1, + RANGE_TYPE(ResExcIoBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + } + + return pRes; +} + +resPtr +xf86PciBusAccWindowsFromOS(void) +{ + sparcDomainPtr pDomain; + resPtr pRes = NULL; + resRange range; + int domain; + + for (domain = 1; domain < pciNumDomains; domain++) { + if (!(pDomain = xf86DomainInfo[domain])) + continue; + + RANGE(range, 0, pDomain->mem_size - 1, + RANGE_TYPE(ResExcMemBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + + RANGE(range, 0, pDomain->io_size - 1, + RANGE_TYPE(ResExcIoBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + } + + return pRes; +} + +resPtr +xf86AccResFromOS(resPtr pRes) +{ + sparcDomainPtr pDomain; + resRange range; + int domain; + + for (domain = 1; domain < pciNumDomains; domain++) { + if (!(pDomain = xf86DomainInfo[domain])) + continue; + + /* + * At minimum, the top and bottom resources must be claimed, so that + * resources that are (or appear to be) unallocated can be relocated. + */ + RANGE(range, 0x00000000u, 0x0009ffffu, + RANGE_TYPE(ResExcMemBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + RANGE(range, 0x000c0000u, 0x000effffu, + RANGE_TYPE(ResExcMemBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + RANGE(range, 0x000f0000u, 0x000fffffu, + RANGE_TYPE(ResExcMemBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + + RANGE(range, pDomain->mem_size - 1, pDomain->mem_size - 1, + RANGE_TYPE(ResExcMemBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + + RANGE(range, 0x00000000u, 0x00000000u, + RANGE_TYPE(ResExcIoBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + RANGE(range, pDomain->io_size - 1, pDomain->io_size - 1, + RANGE_TYPE(ResExcIoBlock, domain)); + pRes = xf86AddResToList(pRes, &range, -1); + } + + return pRes; +} + +#endif /* !INCLUDE_XF86_NO_DOMAIN */ + +#endif /* defined(sun) */ + +#if defined(ARCH_PCI_PCI_BRIDGE) + +/* Definitions specific to Sun's APB P2P bridge (a.k.a. Simba) */ +#define APB_IO_ADDRESS_MAP 0xDE +#define APB_MEM_ADDRESS_MAP 0xDF + +/* + * Simba's can only occur on bus 0. Furthermore, Simba's must have a non-zero + * device/function number because the Sabre interface they must connect to + * occupies the 0:0:0 slot. Also, there can be only one Sabre interface in the + * system, and therefore, only one Simba function can route any particular + * resource. Thus, it is appropriate to use a single set of static variables + * to hold the tag of the Simba function routing a VGA resource range at any + * one time, and to test these variables for non-zero to determine whether or + * not the Sabre would master-abort a VGA access (and kill the system). + * + * The trick is to determine when it is safe to re-route VGA, because doing so + * re-routes much more. + */ +static PCITAG simbavgaIOTag = 0, simbavgaMemTag = 0; +static Bool simbavgaRoutingAllow = TRUE; + +/* + * Scan the bus subtree rooted at 'bus' for a non-display device that might be + * decoding the bottom 2 MB of I/O space and/or the bottom 512 MB of memory + * space. Reset simbavgaRoutingAllow if such a device is found. + * + * XXX For now, this is very conservative and should be made less so as the + * need arises. + */ +static void +simbaCheckBus(CARD16 pcicommand, int bus) +{ + pciConfigPtr pPCI, *ppPCI = xf86scanpci(0); + + while ((pPCI = *ppPCI++)) { + if (pPCI->busnum < bus) + continue; + if (pPCI->busnum > bus) + break; + + /* XXX Assume all devices respect PCI disablement */ + if (!(pcicommand & pPCI->pci_command)) + continue; + + /* XXX This doesn't deal with mis-advertised classes */ + switch (pPCI->pci_base_class) { + case PCI_CLASS_PREHISTORIC: + if (pPCI->pci_sub_class == PCI_SUBCLASS_PREHISTORIC_VGA) + continue; /* Ignore VGA */ + break; + + case PCI_CLASS_DISPLAY: + continue; + + case PCI_CLASS_BRIDGE: + switch (pPCI->pci_sub_class) { + case PCI_SUBCLASS_BRIDGE_PCI: + case PCI_SUBCLASS_BRIDGE_CARDBUS: + /* Scan secondary bus */ + /* XXX First check bridge routing? */ + simbaCheckBus(pcicommand & pPCI->pci_command, + PCI_SECONDARY_BUS_EXTRACT(pPCI->pci_pp_bus_register, + pPCI->tag)); + if (!simbavgaRoutingAllow) + return; + + default: + break; + } + + default: + break; + } + + /* + * XXX We could check the device's bases here, but PCI doesn't limit + * the device's decoding to them. + */ + + simbavgaRoutingAllow = FALSE; + break; + } +} + +static pciConfigPtr +simbaVerifyBus(int bus) +{ + pciConfigPtr pPCI; + if ((bus < 0) || (bus >= pciNumBuses) || + !pciBusInfo[bus] || !(pPCI = pciBusInfo[bus]->bridge) || + (pPCI->pci_device_vendor != DEVID(SUN, SIMBA))) + return NULL; + + return pPCI; +} + +static CARD16 +simbaControlBridge(int bus, CARD16 mask, CARD16 value) +{ + pciConfigPtr pPCI; + CARD16 current = 0, tmp; + CARD8 iomap, memmap; + + if ((pPCI = simbaVerifyBus(bus))) { + /* + * The Simba does not implement VGA enablement as described in the P2P + * spec. It does however route I/O and memory in large enough chunks + * so that we can determine were VGA resources would be routed + * (including ISA VGA I/O aliases). We can allow changes to that + * routing only under certain circumstances. + */ + iomap = pciReadByte(pPCI->tag, APB_IO_ADDRESS_MAP); + memmap = pciReadByte(pPCI->tag, APB_MEM_ADDRESS_MAP); + if (iomap & memmap & 0x01) { + current |= PCI_PCI_BRIDGE_VGA_EN; + if ((mask & PCI_PCI_BRIDGE_VGA_EN) && + !(value & PCI_PCI_BRIDGE_VGA_EN)) { + if (!simbavgaRoutingAllow) { + xf86MsgVerb(X_WARNING, 3, "Attempt to disable VGA routing" + " through Simba at %x:%x:%x disallowed.\n", + pPCI->busnum, pPCI->devnum, pPCI->funcnum); + value |= PCI_PCI_BRIDGE_VGA_EN; + } else { + pciWriteByte(pPCI->tag, APB_IO_ADDRESS_MAP, + iomap & ~0x01); + pciWriteByte(pPCI->tag, APB_MEM_ADDRESS_MAP, + memmap & ~0x01); + simbavgaIOTag = simbavgaMemTag = 0; + } + } + } else { + if (mask & value & PCI_PCI_BRIDGE_VGA_EN) { + if (!simbavgaRoutingAllow) { + xf86MsgVerb(X_WARNING, 3, "Attempt to enable VGA routing" + " through Simba at %x:%x:%x disallowed.\n", + pPCI->busnum, pPCI->devnum, pPCI->funcnum); + value &= ~PCI_PCI_BRIDGE_VGA_EN; + } else { + if (pPCI->tag != simbavgaIOTag) { + if (simbavgaIOTag) { + tmp = pciReadByte(simbavgaIOTag, + APB_IO_ADDRESS_MAP); + pciWriteByte(simbavgaIOTag, APB_IO_ADDRESS_MAP, + tmp & ~0x01); + } + + pciWriteByte(pPCI->tag, APB_IO_ADDRESS_MAP, + iomap | 0x01); + simbavgaIOTag = pPCI->tag; + } + + if (pPCI->tag != simbavgaMemTag) { + if (simbavgaMemTag) { + tmp = pciReadByte(simbavgaMemTag, + APB_MEM_ADDRESS_MAP); + pciWriteByte(simbavgaMemTag, APB_MEM_ADDRESS_MAP, + tmp & ~0x01); + } + + pciWriteByte(pPCI->tag, APB_MEM_ADDRESS_MAP, + memmap | 0x01); + simbavgaMemTag = pPCI->tag; + } + } + } + } + + /* Move on to master abort failure enablement (as per P2P spec) */ + tmp = pciReadWord(pPCI->tag, PCI_PCI_BRIDGE_CONTROL_REG); + current |= tmp; + if (tmp & PCI_PCI_BRIDGE_MASTER_ABORT_EN) { + if ((mask & PCI_PCI_BRIDGE_MASTER_ABORT_EN) && + !(value & PCI_PCI_BRIDGE_MASTER_ABORT_EN)) + pciWriteWord(pPCI->tag, PCI_PCI_BRIDGE_CONTROL_REG, + tmp & ~PCI_PCI_BRIDGE_MASTER_ABORT_EN); + } else { + if (mask & value & PCI_PCI_BRIDGE_MASTER_ABORT_EN) + pciWriteWord(pPCI->tag, PCI_PCI_BRIDGE_CONTROL_REG, + tmp | PCI_PCI_BRIDGE_MASTER_ABORT_EN); + } + + /* Insert emulation of other P2P controls here */ + } + + return (current & ~mask) | (value & mask); +} + +static void +simbaGetBridgeResources(int bus, + pointer *ppIoRes, + pointer *ppMemRes, + pointer *ppPmemRes) +{ + pciConfigPtr pPCI = simbaVerifyBus(bus); + resRange range; + int i; + + if (!pPCI) + return; + + if (ppIoRes) { + xf86FreeResList(*ppIoRes); + *ppIoRes = NULL; + + if (pPCI->pci_command & PCI_CMD_IO_ENABLE) { + unsigned char iomap = pciReadByte(pPCI->tag, APB_IO_ADDRESS_MAP); + if (simbavgaRoutingAllow) + iomap |= 0x01; + for (i = 0; i < 8; i++) { + if (iomap & (1 << i)) { + RANGE(range, i << 21, ((i + 1) << 21) - 1, + RANGE_TYPE(ResExcIoBlock, + xf86GetPciDomain(pPCI->tag))); + *ppIoRes = xf86AddResToList(*ppIoRes, &range, -1); + } + } + } + } + + if (ppMemRes) { + xf86FreeResList(*ppMemRes); + *ppMemRes = NULL; + + if (pPCI->pci_command & PCI_CMD_MEM_ENABLE) { + unsigned char memmap = pciReadByte(pPCI->tag, APB_MEM_ADDRESS_MAP); + if (simbavgaRoutingAllow) + memmap |= 0x01; + for (i = 0; i < 8; i++) { + if (memmap & (1 << i)) { + RANGE(range, i << 29, ((i + 1) << 29) - 1, + RANGE_TYPE(ResExcMemBlock, + xf86GetPciDomain(pPCI->tag))); + *ppMemRes = xf86AddResToList(*ppMemRes, &range, -1); + } + } + } + } + + if (ppPmemRes) { + xf86FreeResList(*ppPmemRes); + *ppPmemRes = NULL; + } +} + +void ARCH_PCI_PCI_BRIDGE(pciConfigPtr pPCI) +{ + static pciBusFuncs_t simbaBusFuncs; + pciBusInfo_t *pBusInfo; + CARD16 pcicommand; + + if (pPCI->pci_device_vendor != DEVID(SUN, SIMBA)) + return; + + pBusInfo = pPCI->businfo; + + simbaBusFuncs = *(pBusInfo->funcs); + simbaBusFuncs.pciControlBridge = simbaControlBridge; + simbaBusFuncs.pciGetBridgeResources = simbaGetBridgeResources; + + pBusInfo->funcs = &simbaBusFuncs; + + if (!simbavgaRoutingAllow) + return; + + pcicommand = 0; + + if (pciReadByte(pPCI->tag, APB_IO_ADDRESS_MAP) & 0x01) { + pcicommand |= PCI_CMD_IO_ENABLE; + simbavgaIOTag = pPCI->tag; + } + + if (pciReadByte(pPCI->tag, APB_MEM_ADDRESS_MAP) & 0x01) { + pcicommand |= PCI_CMD_MEM_ENABLE; + simbavgaMemTag = pPCI->tag; + } + + if (!pcicommand) + return; + + simbaCheckBus(pcicommand, + PCI_SECONDARY_BUS_EXTRACT(pPCI->pci_pp_bus_register, pPCI->tag)); +} + +#endif /* defined(ARCH_PCI_PCI_BRIDGE) */ diff --git a/hw/xfree86/os-support/bus/xf86Pci.h b/hw/xfree86/os-support/bus/xf86Pci.h new file mode 100644 index 000000000..3ffc7d544 --- /dev/null +++ b/hw/xfree86/os-support/bus/xf86Pci.h @@ -0,0 +1,787 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/xf86Pci.h,v 1.36.2.1 2003/03/21 22:29:59 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 is derived in part from the original xf86_PCI.h that included + * following copyright message: + * + * Copyright 1995 by Robin Cutshaw <robin@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 the above listed copyright holder(s) + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. The above listed + * copyright holder(s) make(s) no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * THE ABOVE LISTED COPYRIGHT HOLDER(S) DISCLAIM(S) ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDER(S) 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 contains just the public interface to the PCI code. + * Drivers should use this file rather than Pci.h. + */ + +#ifndef _XF86PCI_H +#define _XF86PCI_H 1 +#include "Xarch.h" +#include "Xfuncproto.h" +#include "misc.h" + +#define PCI_NOT_FOUND 0xFFFFFFFFU + +/* + * PCI cfg space definitions (e.g. stuff right out of the PCI spec) + */ + +/* Device identification register */ +#define PCI_ID_REG 0x00 + +/* Command and status register */ +#define PCI_CMD_STAT_REG 0x04 +#define PCI_CMD_BASE_REG 0x10 +#define PCI_CMD_BIOS_REG 0x30 +#define PCI_CMD_MASK 0xffff +#define PCI_CMD_IO_ENABLE 0x01 +#define PCI_CMD_MEM_ENABLE 0x02 +#define PCI_CMD_MASTER_ENABLE 0x04 +#define PCI_CMD_SPECIAL_ENABLE 0x08 +#define PCI_CMD_INVALIDATE_ENABLE 0x10 +#define PCI_CMD_PALETTE_ENABLE 0x20 +#define PCI_CMD_PARITY_ENABLE 0x40 +#define PCI_CMD_STEPPING_ENABLE 0x80 +#define PCI_CMD_SERR_ENABLE 0x100 +#define PCI_CMD_BACKTOBACK_ENABLE 0x200 +#define PCI_CMD_BIOS_ENABLE 0x01 + +/* base class */ +#define PCI_CLASS_REG 0x08 +#define PCI_CLASS_MASK 0xff000000 +#define PCI_CLASS_SHIFT 24 +#define PCI_CLASS_EXTRACT(x) \ + (((x) & PCI_CLASS_MASK) >> PCI_CLASS_SHIFT) + +/* base class values */ +#define PCI_CLASS_PREHISTORIC 0x00 +#define PCI_CLASS_MASS_STORAGE 0x01 +#define PCI_CLASS_NETWORK 0x02 +#define PCI_CLASS_DISPLAY 0x03 +#define PCI_CLASS_MULTIMEDIA 0x04 +#define PCI_CLASS_MEMORY 0x05 +#define PCI_CLASS_BRIDGE 0x06 +#define PCI_CLASS_COMMUNICATIONS 0x07 +#define PCI_CLASS_SYSPERIPH 0x08 +#define PCI_CLASS_INPUT 0x09 +#define PCI_CLASS_DOCKING 0x0a +#define PCI_CLASS_PROCESSOR 0x0b +#define PCI_CLASS_SERIALBUS 0x0c +#define PCI_CLASS_WIRELESS 0x0d +#define PCI_CLASS_I2O 0x0e +#define PCI_CLASS_SATELLITE 0x0f +#define PCI_CLASS_CRYPT 0x10 +#define PCI_CLASS_DATA_ACQUISTION 0x11 +#define PCI_CLASS_UNDEFINED 0xff + +/* sub class */ +#define PCI_SUBCLASS_MASK 0x00ff0000 +#define PCI_SUBCLASS_SHIFT 16 +#define PCI_SUBCLASS_EXTRACT(x) \ + (((x) & PCI_SUBCLASS_MASK) >> PCI_SUBCLASS_SHIFT) + +/* Sub class values */ +/* 0x00 prehistoric subclasses */ +#define PCI_SUBCLASS_PREHISTORIC_MISC 0x00 +#define PCI_SUBCLASS_PREHISTORIC_VGA 0x01 + +/* 0x01 mass storage subclasses */ +#define PCI_SUBCLASS_MASS_STORAGE_SCSI 0x00 +#define PCI_SUBCLASS_MASS_STORAGE_IDE 0x01 +#define PCI_SUBCLASS_MASS_STORAGE_FLOPPY 0x02 +#define PCI_SUBCLASS_MASS_STORAGE_IPI 0x03 +#define PCI_SUBCLASS_MASS_STORAGE_MISC 0x80 + +/* 0x02 network subclasses */ +#define PCI_SUBCLASS_NETWORK_ETHERNET 0x00 +#define PCI_SUBCLASS_NETWORK_TOKENRING 0x01 +#define PCI_SUBCLASS_NETWORK_FDDI 0x02 +#define PCI_SUBCLASS_NETWORK_MISC 0x80 + +/* 0x03 display subclasses */ +#define PCI_SUBCLASS_DISPLAY_VGA 0x00 +#define PCI_SUBCLASS_DISPLAY_XGA 0x01 +#define PCI_SUBCLASS_DISPLAY_MISC 0x80 + +/* 0x04 multimedia subclasses */ +#define PCI_SUBCLASS_MULTIMEDIA_VIDEO 0x00 +#define PCI_SUBCLASS_MULTIMEDIA_AUDIO 0x01 +#define PCI_SUBCLASS_MULTIMEDIA_MISC 0x80 + +/* 0x05 memory subclasses */ +#define PCI_SUBCLASS_MEMORY_RAM 0x00 +#define PCI_SUBCLASS_MEMORY_FLASH 0x01 +#define PCI_SUBCLASS_MEMORY_MISC 0x80 + +/* 0x06 bridge subclasses */ +#define PCI_SUBCLASS_BRIDGE_HOST 0x00 +#define PCI_SUBCLASS_BRIDGE_ISA 0x01 +#define PCI_SUBCLASS_BRIDGE_EISA 0x02 +#define PCI_SUBCLASS_BRIDGE_MC 0x03 +#define PCI_SUBCLASS_BRIDGE_PCI 0x04 +#define PCI_SUBCLASS_BRIDGE_PCMCIA 0x05 +#define PCI_SUBCLASS_BRIDGE_NUBUS 0x06 +#define PCI_SUBCLASS_BRIDGE_CARDBUS 0x07 +#define PCI_SUBCLASS_BRIDGE_RACEWAY 0x08 +#define PCI_SUBCLASS_BRIDGE_MISC 0x80 +#define PCI_IF_BRIDGE_PCI_SUBTRACTIVE 0x01 + +/* 0x07 communications controller subclasses */ +#define PCI_SUBCLASS_COMMUNICATIONS_SERIAL 0x00 +#define PCI_SUBCLASS_COMMUNICATIONS_PARALLEL 0x01 +#define PCI_SUBCLASS_COMMUNICATIONS_MULTISERIAL 0x02 +#define PCI_SUBCLASS_COMMUNICATIONS_MODEM 0x03 +#define PCI_SUBCLASS_COMMUNICATIONS_MISC 0x80 + +/* 0x08 generic system peripherals subclasses */ +#define PCI_SUBCLASS_SYSPERIPH_PIC 0x00 +#define PCI_SUBCLASS_SYSPERIPH_DMA 0x01 +#define PCI_SUBCLASS_SYSPERIPH_TIMER 0x02 +#define PCI_SUBCLASS_SYSPERIPH_RTC 0x03 +#define PCI_SUBCLASS_SYSPERIPH_HOTPCI 0x04 +#define PCI_SUBCLASS_SYSPERIPH_MISC 0x80 + +/* 0x09 input device subclasses */ +#define PCI_SUBCLASS_INPUT_KEYBOARD 0x00 +#define PCI_SUBCLASS_INPUT_DIGITIZER 0x01 +#define PCI_SUBCLASS_INPUT_MOUSE 0x02 +#define PCI_SUBCLASS_INPUT_SCANNER 0x03 +#define PCI_SUBCLASS_INPUT_GAMEPORT 0x04 +#define PCI_SUBCLASS_INPUT_MISC 0x80 + +/* 0x0a docking station subclasses */ +#define PCI_SUBCLASS_DOCKING_GENERIC 0x00 +#define PCI_SUBCLASS_DOCKING_MISC 0x80 + +/* 0x0b processor subclasses */ +#define PCI_SUBCLASS_PROCESSOR_386 0x00 +#define PCI_SUBCLASS_PROCESSOR_486 0x01 +#define PCI_SUBCLASS_PROCESSOR_PENTIUM 0x02 +#define PCI_SUBCLASS_PROCESSOR_ALPHA 0x10 +#define PCI_SUBCLASS_PROCESSOR_POWERPC 0x20 +#define PCI_SUBCLASS_PROCESSOR_MIPS 0x30 +#define PCI_SUBCLASS_PROCESSOR_COPROC 0x40 + +/* 0x0c serial bus controller subclasses */ +#define PCI_SUBCLASS_SERIAL_FIREWIRE 0x00 +#define PCI_SUBCLASS_SERIAL_ACCESS 0x01 +#define PCI_SUBCLASS_SERIAL_SSA 0x02 +#define PCI_SUBCLASS_SERIAL_USB 0x03 +#define PCI_SUBCLASS_SERIAL_FIBRECHANNEL 0x04 +#define PCI_SUBCLASS_SERIAL_SMBUS 0x05 + +/* 0x0d wireless controller subclasses */ +#define PCI_SUBCLASS_WIRELESS_IRDA 0x00 +#define PCI_SUBCLASS_WIRELESS_CONSUMER_IR 0x01 +#define PCI_SUBCLASS_WIRELESS_RF 0x02 +#define PCI_SUBCLASS_WIRELESS_MISC 0x80 + +/* 0x0e intelligent I/O controller subclasses */ +#define PCI_SUBCLASS_I2O_I2O 0x00 + +/* 0x0f satellite communications controller subclasses */ +#define PCI_SUBCLASS_SATELLITE_TV 0x01 +#define PCI_SUBCLASS_SATELLITE_AUDIO 0x02 +#define PCI_SUBCLASS_SATELLITE_VOICE 0x03 +#define PCI_SUBCLASS_SATELLITE_DATA 0x04 + +/* 0x10 encryption/decryption controller subclasses */ +#define PCI_SUBCLASS_CRYPT_NET_COMPUTING 0x00 +#define PCI_SUBCLASS_CRYPT_ENTERTAINMENT 0x10 +#define PCI_SUBCLASS_CRYPT_MISC 0x80 + +/* 0x11 data acquisition and signal processing controller subclasses */ +#define PCI_SUBCLASS_DATAACQ_DPIO 0x00 +#define PCI_SUBCLASS_DATAACQ_MISC 0x80 + + +/* Header */ +#define PCI_HEADER_MISC 0x0c +#define PCI_HEADER_MULTIFUNCTION 0x00800000 + +/* Interrupt configration register */ +#define PCI_INTERRUPT_REG 0x3c +#define PCI_INTERRUPT_PIN_MASK 0x0000ff00 +#define PCI_INTERRUPT_PIN_EXTRACT(x) \ + ((((x) & PCI_INTERRUPT_PIN_MASK) >> 8) & 0xff) +#define PCI_INTERRUPT_PIN_NONE 0x00 +#define PCI_INTERRUPT_PIN_A 0x01 +#define PCI_INTERRUPT_PIN_B 0x02 +#define PCI_INTERRUPT_PIN_C 0x03 +#define PCI_INTERRUPT_PIN_D 0x04 + +#define PCI_INTERRUPT_LINE_MASK 0x000000ff +#define PCI_INTERRUPT_LINE_EXTRACT(x) \ + ((((x) & PCI_INTERRUPT_LINE_MASK) >> 0) & 0xff) +#define PCI_INTERRUPT_LINE_INSERT(x,v) \ + (((x) & ~PCI_INTERRUPT_LINE_MASK) | ((v) << 0)) + +/* Base registers */ +#define PCI_MAP_REG_START 0x10 +#define PCI_MAP_REG_END 0x28 +#define PCI_MAP_ROM_REG 0x30 + +#define PCI_MAP_MEMORY 0x00000000 +#define PCI_MAP_IO 0x00000001 + +#define PCI_MAP_MEMORY_TYPE 0x00000007 +#define PCI_MAP_IO_TYPE 0x00000003 + +#define PCI_MAP_MEMORY_TYPE_32BIT 0x00000000 +#define PCI_MAP_MEMORY_TYPE_32BIT_1M 0x00000002 +#define PCI_MAP_MEMORY_TYPE_64BIT 0x00000004 +#define PCI_MAP_MEMORY_TYPE_MASK 0x00000006 +#define PCI_MAP_MEMORY_CACHABLE 0x00000008 +#define PCI_MAP_MEMORY_ATTR_MASK 0x0000000e +#define PCI_MAP_MEMORY_ADDRESS_MASK 0xfffffff0 + +#define PCI_MAP_IO_ATTR_MASK 0x00000003 + +#define PCI_MAP_IS_IO(b) ((b) & PCI_MAP_IO) +#define PCI_MAP_IS_MEM(b) (!PCI_MAP_IS_IO(b)) + +#define PCI_MAP_IS64BITMEM(b) \ + (((b) & PCI_MAP_MEMORY_TYPE_MASK) == PCI_MAP_MEMORY_TYPE_64BIT) + +#define PCIGETMEMORY(b) ((b) & PCI_MAP_MEMORY_ADDRESS_MASK) +#define PCIGETMEMORY64HIGH(b) (*((CARD32*)&b + 1)) +#define PCIGETMEMORY64(b) \ + (PCIGETMEMORY(b) | ((CARD64)PCIGETMEMORY64HIGH(b) << 32)) + +#define PCI_MAP_IO_ADDRESS_MASK 0xfffffffc + +#define PCIGETIO(b) ((b) & PCI_MAP_IO_ADDRESS_MASK) + +#define PCI_MAP_ROM_DECODE_ENABLE 0x00000001 +#define PCI_MAP_ROM_ADDRESS_MASK 0xfffff800 + +#define PCIGETROM(b) ((b) & PCI_MAP_ROM_ADDRESS_MASK) + +/* PCI-PCI bridge mapping registers */ +#define PCI_PCI_BRIDGE_BUS_REG 0x18 +#define PCI_SUBORDINATE_BUS_MASK 0x00ff0000 +#define PCI_SECONDARY_BUS_MASK 0x0000ff00 +#define PCI_PRIMARY_BUS_MASK 0x000000ff + +#define PCI_PCI_BRIDGE_IO_REG 0x1c +#define PCI_PCI_BRIDGE_MEM_REG 0x20 +#define PCI_PCI_BRIDGE_PMEM_REG 0x24 + +#define PCI_PPB_IOBASE_EXTRACT(x) (((x) << 8) & 0xFF00) +#define PCI_PPB_IOLIMIT_EXTRACT(x) (((x) << 0) & 0xFF00) + +#define PCI_PPB_MEMBASE_EXTRACT(x) (((x) << 16) & 0xFFFF0000) +#define PCI_PPB_MEMLIMIT_EXTRACT(x) (((x) << 0) & 0xFFFF0000) + +#define PCI_PCI_BRIDGE_CONTROL_REG 0x3E +#define PCI_PCI_BRIDGE_PARITY_EN 0x01 +#define PCI_PCI_BRIDGE_SERR_EN 0x02 +#define PCI_PCI_BRIDGE_ISA_EN 0x04 +#define PCI_PCI_BRIDGE_VGA_EN 0x08 +#define PCI_PCI_BRIDGE_MASTER_ABORT_EN 0x20 +#define PCI_PCI_BRIDGE_SECONDARY_RESET 0x40 +#define PCI_PCI_BRIDGE_FAST_B2B_EN 0x80 +/* header type 2 extensions */ +#define PCI_CB_BRIDGE_CTL_CB_RESET 0x40 /* CardBus reset */ +#define PCI_CB_BRIDGE_CTL_16BIT_INT 0x80 /* Enable interrupt for 16-bit cards */ +#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM0 0x100 +#define PCI_CB_BRIDGE_CTL_PREFETCH_MEM1 0x200 +#define PCI_CB_BRIDGE_CTL_POST_WRITES 0x400 + +#define PCI_CB_SEC_STATUS_REG 0x16 /* Secondary status */ +#define PCI_CB_PRIMARY_BUS_REG 0x18 /* PCI bus number */ +#define PCI_CB_CARD_BUS_REG 0x19 /* CardBus bus number */ +#define PCI_CB_SUBORDINATE_BUS_REG 0x1a /* Subordinate bus number */ +#define PCI_CB_LATENCY_TIMER_REG 0x1b /* CardBus latency timer */ +#define PCI_CB_MEM_BASE_0_REG 0x1c +#define PCI_CB_MEM_LIMIT_0_REG 0x20 +#define PCI_CB_MEM_BASE_1_REG 0x24 +#define PCI_CB_MEM_LIMIT_1_REG 0x28 +#define PCI_CB_IO_BASE_0_REG 0x2c +#define PCI_CB_IO_LIMIT_0_REG 0x30 +#define PCI_CB_IO_BASE_1_REG 0x34 +#define PCI_CB_IO_LIMIT_1_REG 0x38 +#define PCI_CB_BRIDGE_CONTROL_REG 0x3E + +#define PCI_CB_IO_RANGE_MASK ~0x03 +#define PCI_CB_IOBASE(x) (x & PCI_CB_IO_RANGE_MASK) +#define PCI_CB_IOLIMIT(x) ((x & PCI_CB_IO_RANGE_MASK) + 3) + +/* Subsystem identification register */ +#define PCI_SUBSYSTEM_ID_REG 0x2c + +/* User defined cfg space regs */ +#define PCI_REG_USERCONFIG 0x40 +#define PCI_OPTION_REG 0x40 + +/* + * Typedefs, etc... + */ + +/* Primitive Types */ +typedef unsigned long ADDRESS; /* Memory/PCI address */ +typedef unsigned long IOADDRESS; /* Must be large enough for a pointer */ +typedef unsigned long PCITAG; + +/* + * PCI configuration space + */ +typedef struct pci_cfg_regs { + /* start of official PCI config space header */ + union { /* Offset 0x0 - 0x3 */ + CARD32 device_vendor; + struct { +#if X_BYTE_ORDER == X_BIG_ENDIAN + CARD16 device; + CARD16 vendor; +#else + CARD16 vendor; + CARD16 device; +#endif + } dv; + } dv_id; + + union { /* Offset 0x4 - 0x8 */ + CARD32 status_command; + struct { +#if X_BYTE_ORDER == X_BIG_ENDIAN + CARD16 status; + CARD16 command; +#else + CARD16 command; + CARD16 status; +#endif + } sc; + } stat_cmd; + + union { /* Offset 0x8 - 0xb */ + CARD32 class_revision; + struct { +#if X_BYTE_ORDER == X_BIG_ENDIAN + CARD8 base_class; + CARD8 sub_class; + CARD8 prog_if; + CARD8 rev_id; +#else + CARD8 rev_id; + CARD8 prog_if; + CARD8 sub_class; + CARD8 base_class; +#endif + } cr; + } class_rev; + + union { /* Offset 0xc - 0xf */ + CARD32 bist_header_latency_cache; + struct { +#if X_BYTE_ORDER == X_BIG_ENDIAN + CARD8 bist; + CARD8 header_type; + CARD8 latency_timer; + CARD8 cache_line_size; +#else + CARD8 cache_line_size; + CARD8 latency_timer; + CARD8 header_type; + CARD8 bist; +#endif + } bhlc; + } bhlc; + union { /* Offset 0x10 - 0x3b */ + struct { /* header type 2 */ + CARD32 cg_rsrvd1; /* 0x10 */ +#if X_BYTE_ORDER == X_BIG_ENDIAN + CARD16 secondary_status; /* 0x16 */ + CARD16 cg_rsrvd2; /* 0x14 */ + + union { + CARD32 cg_bus_reg; + struct { + CARD8 latency_timer; /* 0x1b */ + CARD8 subordinate_bus_number; /* 0x1a */ + CARD8 cardbus_bus_number; /* 0x19 */ + CARD8 primary_bus_number; /* 0x18 */ + } cgbr; + } cgbr; +#else + CARD16 cg_rsrvd2; /* 0x14 */ + CARD16 secondary_status; /* 0x16 */ + + union { + CARD32 cg_bus_reg; + struct { + CARD8 primary_bus_number; /* 0x18 */ + CARD8 cardbus_bus_number; /* 0x19 */ + CARD8 subordinate_bus_number; /* 0x1a */ + CARD8 latency_timer; /* 0x1b */ + } cgbr; + } cgbr; +#endif + CARD32 mem_base0; /* 0x1c */ + CARD32 mem_limit0; /* 0x20 */ + CARD32 mem_base1; /* 0x24 */ + CARD32 mem_limit1; /* 0x28 */ + CARD32 io_base0; /* 0x2c */ + CARD32 io_limit0; /* 0x30 */ + CARD32 io_base1; /* 0x34 */ + CARD32 io_limit1; /* 0x38 */ + } cg; + struct { + union { /* Offset 0x10 - 0x27 */ + struct { /* header type 0 */ + CARD32 dv_base0; + CARD32 dv_base1; + CARD32 dv_base2; + CARD32 dv_base3; + CARD32 dv_base4; + CARD32 dv_base5; + } dv; + struct { /* header type 1 */ + CARD32 bg_rsrvd[2]; +#if X_BYTE_ORDER == X_BIG_ENDIAN + union { + CARD32 pp_bus_reg; + struct { + CARD8 secondary_latency_timer; + CARD8 subordinate_bus_number; + CARD8 secondary_bus_number; + CARD8 primary_bus_number; + } ppbr; + } ppbr; + + CARD16 secondary_status; + CARD8 io_limit; + CARD8 io_base; + + CARD16 mem_limit; + CARD16 mem_base; + + CARD16 prefetch_mem_limit; + CARD16 prefetch_mem_base; +#else + union { + CARD32 pp_bus_reg; + struct { + CARD8 primary_bus_number; + CARD8 secondary_bus_number; + CARD8 subordinate_bus_number; + CARD8 secondary_latency_timer; + } ppbr; + } ppbr; + + CARD8 io_base; + CARD8 io_limit; + CARD16 secondary_status; + + CARD16 mem_base; + CARD16 mem_limit; + + CARD16 prefetch_mem_base; + CARD16 prefetch_mem_limit; +#endif + } bg; + } bc; + union { /* Offset 0x28 - 0x2b */ + CARD32 rsvd1; + CARD32 pftch_umem_base; + CARD32 cardbus_cis_ptr; + } um_c_cis; + union { /* Offset 0x2c - 0x2f */ + CARD32 subsys_card_vendor; + CARD32 pftch_umem_limit; + CARD32 rsvd2; + struct { +#if X_BYTE_ORDER == X_BIG_ENDIAN + CARD16 subsys_card; + CARD16 subsys_vendor; +#else + CARD16 subsys_vendor; + CARD16 subsys_card; +#endif + } ssys; + } um_ssys_id; + union { /* Offset 0x30 - 0x33 */ + CARD32 baserom; + struct { +#if X_BYTE_ORDER == X_BIG_ENDIAN + CARD16 io_ulimit; + CARD16 io_ubase; +#else + CARD16 io_ubase; + CARD16 io_ulimit; +#endif + } b_u_io; + } uio_rom; + struct { + CARD32 rsvd3; /* Offset 0x34 - 0x37 */ + CARD32 rsvd4; /* Offset 0x38 - 0x3b */ + } rsvd; + } cd; + } cx; + union { /* Offset 0x3c - 0x3f */ + union { /* header type 0 */ + CARD32 max_min_ipin_iline; + struct { +#if X_BYTE_ORDER == X_BIG_ENDIAN + CARD8 max_lat; + CARD8 min_gnt; + CARD8 int_pin; + CARD8 int_line; +#else + CARD8 int_line; + CARD8 int_pin; + CARD8 min_gnt; + CARD8 max_lat; +#endif + } mmii; + } mmii; + struct { /* header type 1 */ +#if X_BYTE_ORDER == X_BIG_ENDIAN + CARD16 bridge_control; /* upper 8 bits reserved */ + CARD8 rsvd2; + CARD8 rsvd1; +#else + CARD8 rsvd1; + CARD8 rsvd2; + CARD16 bridge_control; /* upper 8 bits reserved */ +#endif + } bctrl; + } bm; + union { /* Offset 0x40 - 0xff */ + CARD32 dwords[48]; + CARD8 bytes[192]; + } devspf; +} pciCfgRegs; + +typedef union pci_cfg_spc { + pciCfgRegs regs; + CARD32 dwords[256/sizeof(CARD32)]; + CARD8 bytes[256/sizeof(CARD8)]; +} pciCfgSpc; + +/* + * Data structure returned by xf86scanpci including contents of + * PCI config space header + */ +typedef struct pci_device { + PCITAG tag; + int busnum; + int devnum; + int funcnum; + pciCfgSpc cfgspc; + int basesize[7]; /* number of bits in base addr allocations */ + Bool minBasesize; + CARD32 listed_class; + pointer businfo; /* pointer to secondary's bus info structure */ + Bool fakeDevice; /* Device added by system chipset support */ +} pciDevice, *pciConfigPtr; + +typedef enum { + WRITE, + READ, + SET_BITS +} pciFunc; + +typedef enum { + PCI_MEM, + PCI_MEM_SIZE, + PCI_MEM_SPARSE_BASE, + PCI_MEM_SPARSE_MASK, + PCI_IO, + PCI_IO_SIZE, + PCI_IO_SPARSE_BASE, + PCI_IO_SPARSE_MASK +} PciAddrType; + +#define pci_device_vendor cfgspc.regs.dv_id.device_vendor +#define pci_vendor cfgspc.regs.dv_id.dv.vendor +#define pci_device cfgspc.regs.dv_id.dv.device +#define pci_status_command cfgspc.regs.stat_cmd.status_command +#define pci_command cfgspc.regs.stat_cmd.sc.command +#define pci_status cfgspc.regs.stat_cmd.sc.status +#define pci_class_revision cfgspc.regs.class_rev.class_revision +#define pci_rev_id cfgspc.regs.class_rev.cr.rev_id +#define pci_prog_if cfgspc.regs.class_rev.cr.prog_if +#define pci_sub_class cfgspc.regs.class_rev.cr.sub_class +#define pci_base_class cfgspc.regs.class_rev.cr.base_class +#define pci_bist_header_latency_cache cfgspc.regs.bhlc.bist_header_latency_cache +#define pci_cache_line_size cfgspc.regs.bhlc.bhlc.cache_line_size +#define pci_latency_timer cfgspc.regs.bhlc.bhlc.latency_timer +#define pci_header_type cfgspc.regs.bhlc.bhlc.header_type +#define pci_bist cfgspc.regs.bhlc.bhlc.bist +#define pci_cb_secondary_status cfgspc.regs.cx.cg.secondary_status +#define pci_cb_bus_register cfgspc.regs.cx.cg.cgbr.cg_bus_reg +#define pci_cb_primary_bus_number cfgspc.regs.cx.cg.cgbr.cgbr.primary_bus_number +#define pci_cb_cardbus_bus_number cfgspc.regs.cx.cg.cgbr.cgbr.cardbus_bus_number +#define pci_cb_subordinate_bus_number cfgspc.regs.cx.cg.cgbr.cgbr.subordinate_bus_number +#define pci_cb_latency_timer cfgspc.regs.cx.cg.cgbr.cgbr.latency_timer +#define pci_cb_membase0 cfgspc.regs.cx.cg.mem_base0 +#define pci_cb_memlimit0 cfgspc.regs.cx.cg.mem_limit0 +#define pci_cb_membase1 cfgspc.regs.cx.cg.mem_base1 +#define pci_cb_memlimit1 cfgspc.regs.cx.cg.mem_limit1 +#define pci_cb_iobase0 cfgspc.regs.cx.cg.io_base0 +#define pci_cb_iolimit0 cfgspc.regs.cx.cg.io_limit0 +#define pci_cb_iobase1 cfgspc.regs.cx.cg.io_base1 +#define pci_cb_iolimit1 cfgspc.regs.cx.cg.io_limit1 +#define pci_base0 cfgspc.regs.cx.cd.bc.dv.dv_base0 +#define pci_base1 cfgspc.regs.cx.cd.bc.dv.dv_base1 +#define pci_base2 cfgspc.regs.cx.cd.bc.dv.dv_base2 +#define pci_base3 cfgspc.regs.cx.cd.bc.dv.dv_base3 +#define pci_base4 cfgspc.regs.cx.cd.bc.dv.dv_base4 +#define pci_base5 cfgspc.regs.cx.cd.bc.dv.dv_base5 +#define pci_cardbus_cis_ptr cfgspc.regs.cx.cd.umem_c_cis.cardbus_cis_ptr +#define pci_subsys_card_vendor cfgspc.regs.cx.cd.um_ssys_id.subsys_card_vendor +#define pci_subsys_vendor cfgspc.regs.cx.cd.um_ssys_id.ssys.subsys_vendor +#define pci_subsys_card cfgspc.regs.cx.cd.um_ssys_id.ssys.subsys_card +#define pci_baserom cfgspc.regs.cx.cd.uio_rom.baserom +#define pci_pp_bus_register cfgspc.regs.cx.cd.bc.bg.ppbr.pp_bus_reg +#define pci_primary_bus_number cfgspc.regs.cx.cd.bc.bg.ppbr.ppbr.primary_bus_number +#define pci_secondary_bus_number cfgspc.regs.cx.cd.bc.bg.ppbr.ppbr.secondary_bus_number +#define pci_subordinate_bus_number cfgspc.regs.cx.cd.bc.bg.ppbr.ppbr.subordinate_bus_number +#define pci_secondary_latency_timer cfgspc.regs.cx.cd.bc.bg.ppbr.ppbr.secondary_latency_timer +#define pci_io_base cfgspc.regs.cx.cd.bc.bg.io_base +#define pci_io_limit cfgspc.regs.cx.cd.bc.bg.io_limit +#define pci_secondary_status cfgspc.regs.cx.cd.bc.bg.secondary_status +#define pci_mem_base cfgspc.regs.cx.cd.bc.bg.mem_base +#define pci_mem_limit cfgspc.regs.cx.cd.bc.bg.mem_limit +#define pci_prefetch_mem_base cfgspc.regs.cx.cd.bc.bg.prefetch_mem_base +#define pci_prefetch_mem_limit cfgspc.regs.cx.cd.bc.bg.prefetch_mem_limit +#define pci_rsvd1 cfgspc.regs.cx.cd.um_c_cis.rsvd1 +#define pci_rsvd2 cfgspc.regs.cx.cd.um_ssys_id.rsvd2 +#define pci_prefetch_upper_mem_base cfgspc.regs.cx.cd.um_c_cis.pftch_umem_base +#define pci_prefetch_upper_mem_limit cfgspc.regs.cx.cd.um_ssys_id.pftch_umem_limit +#define pci_upper_io_base cfgspc.regs.cx.cd.uio_rom.b_u_io.io_ubase +#define pci_upper_io_limit cfgspc.regs.cx.cd.uio_rom.b_u_io.io_ulimit +#define pci_int_line cfgspc.regs.bm.mmii.mmii.int_line +#define pci_int_pin cfgspc.regs.bm.mmii.mmii.int_pin +#define pci_min_gnt cfgspc.regs.bm.mmii.mmii.min_gnt +#define pci_max_lat cfgspc.regs.bm.mmii.mmii.max_lat +#define pci_max_min_ipin_iline cfgspc.regs.bm.mmii.max_min_ipin_iline +#define pci_bridge_control cfgspc.regs.bm.bctrl.bridge_control +#define pci_user_config cfgspc.regs.devspf.dwords[0] +#define pci_user_config_0 cfgspc.regs.devspf.bytes[0] +#define pci_user_config_1 cfgspc.regs.devspf.bytes[1] +#define pci_user_config_2 cfgspc.regs.devspf.bytes[2] +#define pci_user_config_3 cfgspc.regs.devspf.bytes[3] + +typedef enum { + PCI_BIOS_PC = 0, + PCI_BIOS_OPEN_FIRMARE, + PCI_BIOS_HP_PA_RISC, + PCI_BIOS_OTHER +} PciBiosType; + +/* Public PCI access functions */ +void pciInit(void); +PCITAG pciFindFirst(CARD32 id, CARD32 mask); +PCITAG pciFindNext(void); +CARD32 pciReadLong(PCITAG tag, int offset); +CARD16 pciReadWord(PCITAG tag, int offset); +CARD8 pciReadByte(PCITAG tag, int offset); +void pciWriteLong(PCITAG tag, int offset, CARD32 val); +void pciWriteWord(PCITAG tag, int offset, CARD16 val); +void pciWriteByte(PCITAG tag, int offset, CARD8 val); +void pciSetBitsLong(PCITAG tag, int offset, CARD32 mask, CARD32 val); +void pciSetBitsByte(PCITAG tag, int offset, CARD8 mask, CARD8 val); +pointer pciLongFunc(PCITAG tag, pciFunc func); +ADDRESS pciBusAddrToHostAddr(PCITAG tag, PciAddrType type, ADDRESS addr); +ADDRESS pciHostAddrToBusAddr(PCITAG tag, PciAddrType type, ADDRESS addr); +PCITAG pciTag(int busnum, int devnum, int funcnum); +int pciGetBaseSize(PCITAG tag, int indx, Bool destructive, Bool *min); +CARD32 pciCheckForBrokenBase(PCITAG tag,int basereg); +pointer xf86MapPciMem(int ScreenNum, int Flags, PCITAG Tag, + ADDRESS Base, unsigned long Size); +int xf86ReadPciBIOS(unsigned long Offset, PCITAG Tag, int basereg, + unsigned char *Buf, int Len); +int xf86ReadPciBIOSByType(unsigned long Offset, PCITAG Tag, + int basereg, unsigned char *Buf, + int Len, PciBiosType Type); +int xf86GetAvailablePciBIOSTypes(PCITAG Tag, int basereg, + PciBiosType *Buf); +pciConfigPtr *xf86scanpci(int flags); + +extern int pciNumBuses; + +/* Domain access functions. Some of these probably shouldn't be public */ +int xf86GetPciDomain(PCITAG tag); +pointer xf86MapDomainMemory(int ScreenNum, int Flags, PCITAG Tag, + ADDRESS Base, unsigned long Size); +IOADDRESS xf86MapDomainIO(int ScreenNum, int Flags, PCITAG Tag, + IOADDRESS Base, unsigned long Size); +int xf86ReadDomainMemory(PCITAG Tag, ADDRESS Base, int Len, + unsigned char *Buf); + +typedef enum { + ROM_BASE_PRESET = -2, + ROM_BASE_BIOS, + ROM_BASE_MEM0 = 0, + ROM_BASE_MEM1, + ROM_BASE_MEM2, + ROM_BASE_MEM3, + ROM_BASE_MEM4, + ROM_BASE_MEM5, + ROM_BASE_FIND +} romBaseSource; + +#endif /* _XF86PCI_H */ diff --git a/hw/xfree86/os-support/bus/xf86Sbus.h b/hw/xfree86/os-support/bus/xf86Sbus.h new file mode 100644 index 000000000..5c8acfd4b --- /dev/null +++ b/hw/xfree86/os-support/bus/xf86Sbus.h @@ -0,0 +1,59 @@ +/* + * Platform specific SBUS and OpenPROM access declarations. + * + * Copyright (C) 2000 Jakub Jelinek (jakub@redhat.com) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * JAKUB JELINEK BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/xf86Sbus.h,v 1.5 2002/05/22 21:38:30 herrb Exp $ */ + +#ifndef _XF86_SBUS_H +#define _XF86_SBUS_H + +#if defined(linux) +#include <asm/types.h> +#include <asm/fbio.h> +#include <asm/openpromio.h> +#elif defined(SVR4) +#include <sys/fbio.h> +#include <sys/openpromio.h> +#elif defined(__OpenBSD__) && defined(__sparc64__) +/* XXX */ +#elif defined(CSRG_BASED) +#include <machine/fbio.h> +#else +#include <sun/fbio.h> +#endif + +#ifndef FBTYPE_SUNGP3 +#define FBTYPE_SUNGP3 -1 +#endif +#ifndef FBTYPE_MDICOLOR +#define FBTYPE_MDICOLOR -1 +#endif +#ifndef FBTYPE_SUNLEO +#define FBTYPE_SUNLEO -1 +#endif +#ifndef FBTYPE_TCXCOLOR +#define FBTYPE_TCXCOLOR -1 +#endif +#ifndef FBTYPE_CREATOR +#define FBTYPE_CREATOR -1 +#endif + +#endif /* _XF86_SBUS_H */ diff --git a/hw/xfree86/os-support/bus/zx1PCI.c b/hw/xfree86/os-support/bus/zx1PCI.c new file mode 100644 index 000000000..dc4d062f3 --- /dev/null +++ b/hw/xfree86/os-support/bus/zx1PCI.c @@ -0,0 +1,1047 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/zx1PCI.c,v 1.1 2003/02/23 20:26:49 tsi Exp $ */ +/* + * Copyright (C) 2002-2003 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ + +/* + * This file contains the glue necessary for support of HP's ZX1 chipset. + * Keep in mind that this chipset is used in both Itanium2 and PA-RISC + * architectures. + */ + +#include "zx1PCI.h" +#include "xf86.h" +#include "xf86_OSlib.h" +#include "Pci.h" + +#define MIO_BASE 0xFED00000UL /* mio register base */ +#define MIO_SIZE 0x00002000UL /* 8k, minimum */ + +/* ZX1 mio register definitions */ +#define MIO_FUNCTION0 0x0000U + +#define MODULE_INFO 0x0100U +#define STATUS_CONTROL 0x0108U +#define DILLON_PRESENT 0x02UL + +#define LMMIO_DIR_BASE0 0x0300U +#define LMMIO_DIR_MASK0 0x0308U +#define LMMIO_DIR_ROUTE0 0x0310U +#define LMMIO_DIR_BASE1 0x0318U +#define LMMIO_DIR_MASK1 0x0320U +#define LMMIO_DIR_ROUTE1 0x0328U +#define LMMIO_DIR_BASE2 0x0330U +#define LMMIO_DIR_MASK2 0x0338U +#define LMMIO_DIR_ROUTE2 0x0340U +#define LMMIO_DIR_BASE3 0x0348U +#define LMMIO_DIR_MASK3 0x0350U +#define LMMIO_DIR_ROUTE3 0x0358U +#define LMMIO_DIST_BASE 0x0360U +#define LMMIO_DIST_MASK 0x0368U +#define LMMIO_DIST_ROUTE 0x0370U +#define GMMIO_DIST_BASE 0x0378U +#define PORT_DISABLE 0x02UL +#define MAP_TO_LMMIO 0x04UL +#define GMMIO_DIST_MASK 0x0380U +#define GMMIO_DIST_ROUTE 0x0388U +#define IOS_DIST_BASE 0x0390U +#define IOS_DIST_MASK 0x0398U +#define IOS_DIST_ROUTE 0x03A0U +#define ROPE_CONFIG_BASE 0x03A8U +#define VGA_ROUTE 0x03B0U +#define VGA_ENABLE 0x8000000000000000UL +#define VGA_LIGHT 0x4000000000000000UL + +#define IOS_DIR_BASE 0x03C0U +#define IOS_DIR_MASK 0x03C8U +#define IOS_DIR_ROUTE 0x03D0U +#define IOS_BASE 0x03D8U + +#define MIO_FUNCTION1 0x1000U + +#define ROPE_CONFIG 0x1040U +#define ROPE_D0 0x0100UL +#define ROPE_D2 0x0200UL +#define ROPE_D4 0x0400UL +#define ROPE_D6 0x0800UL +#define ROPE_Q0 0x1000UL +#define ROPE_Q4 0x2000UL + +#define LBA_PORT0_CNTRL 0x1200U +#define LBA_PORT1_CNTRL 0x1208U +#define LBA_PORT2_CNTRL 0x1210U +#define LBA_PORT3_CNTRL 0x1218U +#define LBA_PORT4_CNTRL 0x1220U +#define LBA_PORT5_CNTRL 0x1228U +#define LBA_PORT6_CNTRL 0x1230U +#define LBA_PORT7_CNTRL 0x1238U +#define LBA_HARD_FAIL 0x40UL + +#define ROPE_PAGE_CONTROL 0x1418U + +/* + * Total ioa configuration space size is actually 128k, but we only need the + * first 64k. + */ +#define IOA_SIZE 0x00010000UL + +/* ZX1 ioa register definitions */ +#define IOA_CONFIG_ADDR 0x0040U +#define IOA_CONFIG_DATA 0x0048U + +#define IOA_SECONDARY_BUS 0x0058U +#define IOA_SUBORDINATE_BUS 0x0059U + +#define IOA_CONTROL 0x0108U +#define IOA_FORWARD_VGA 0x08UL +#define IOA_HARD_FAIL 0x40UL + +#define IOA_LMMIO_BASE 0x0200U +#define IOA_LMMIO_MASK 0x0208U +#define IOA_GMMIO_BASE 0x0210U +#define IOA_GMMIO_MASK 0x0218U +#define IOA_WLMMIO_BASE 0x0220U +#define IOA_WLMMIO_MASK 0x0228U +#define IOA_WGMMIO_BASE 0x0230U +#define IOA_WGMMIO_MASK 0x0238U +#define IOA_IOS_BASE 0x0240U +#define IOA_IOS_MASK 0x0248U +#define IOA_ELMMIO_BASE 0x0250U +#define IOA_ELMMIO_MASK 0x0258U +#define IOA_EIOS_BASE 0x0260U +#define IOA_EIOS_MASK 0x0268U + +#define IOA_SLAVE_CONTROL 0x0278U +#define IOA_VGA_PEER_ENABLE 0x2000UL +#define IOA_MSI_BASE 0x0280U +#define IOA_MSI_MASK 0x0288U + +#define RANGE_ENABLE 0x01UL /* In various base registers */ + +#define IO_MASK ((1UL << 16) - 1UL) +#define LMMIO_MASK ((1UL << 32) - 1UL) +#ifdef __ia64__ +#define GMMIO_MASK ((1UL << 44) - 1UL) +#else /* PA-RISC */ +#define GMMIO_MASK ((1UL << 40) - 1UL) +#endif + +#define PDH_START 0xFF000000UL +#define PDH_LAST 0xFFFFFFFFUL + +static CARD8 *pZX1mio = NULL, + *pZX1ioa = NULL; + +static INT8 zx1_ropemap[8]; /* One for each (potential) rope */ +static CARD64 zx1_lbacntl[8]; /* " " " " " */ +static int zx1_busno[8], zx1_subno[8]; + +static pciBusFuncs_t zx1BusFuncs; +static int zx1_fakebus = -1; +static Bool zx1_hasvga = FALSE; + +static pointer pZX1IoRes[8], pZX1MemRes[8]; /* Rope resources */ + +/* Non-PCI configuration space access macros */ +#define MIO_BYTE(offset) \ + (*(volatile CARD8 *)(pointer)(pZX1mio + (offset))) +#define MIO_WORD(offset) \ + (*(volatile CARD16 *)(pointer)(pZX1mio + (offset))) +#define MIO_LONG(offset) \ + (*(volatile CARD32 *)(pointer)(pZX1mio + (offset))) +#define MIO_QUAD(offset) \ + (*(volatile CARD64 *)(pointer)(pZX1mio + (offset))) +#define IOA_BYTE(ioa, offset) \ + (*(volatile CARD8 *)(pointer)(pZX1ioa + ((offset) + ((ioa) << 13)))) +#define IOA_WORD(ioa, offset) \ + (*(volatile CARD16 *)(pointer)(pZX1ioa + ((offset) + ((ioa) << 13)))) +#define IOA_LONG(ioa, offset) \ + (*(volatile CARD32 *)(pointer)(pZX1ioa + ((offset) + ((ioa) << 13)))) +#define IOA_QUAD(ioa, offset) \ + (*(volatile CARD64 *)(pointer)(pZX1ioa + ((offset) + ((ioa) << 13)))) + +/* Range definitions */ +#define MAX_RANGE 16 +static CARD64 bot[MAX_RANGE], top[MAX_RANGE], msk[MAX_RANGE], siz[MAX_RANGE]; +static INT8 *pDecode[MAX_RANGE]; +static int nRange = 0; + +/* Track a resource range and assign a granularity to it */ +static void +SetRange(CARD64 base, CARD64 last, CARD8 width) +{ + int i; + + bot[nRange] = base; + top[nRange] = last; + msk[nRange] = (CARD64)(-1L); + if (base) + msk[nRange] &= (base ^ (base - 1UL)) >> 1; + if (last + 1UL) + msk[nRange] &= (last ^ (last + 1UL)) >> 1; + if (width < 64) + msk[nRange] &= (1UL << width) - 1UL; + + /* Look for overlapping ranges */ + for (i = 0; i < nRange; i++) { + if ((bot[i] > top[i]) || + (top[nRange] < bot[i]) || + (top[i] < bot[nRange])) + continue; + + /* Merge in overlapping range */ + if (bot[nRange] > bot[i]) + bot[nRange] = bot[i]; + if (top[nRange] < top[i]) + top[nRange] = top[i]; + + /* Assign finer granularity */ + msk[nRange] &= msk[i]; + bot[i] = 1UL; + top[i] = 0; + } + + nRange++; +} + +/* Lookup granularity associated with the range containing 'base' */ +static int +GetRange(CARD64 base) +{ + int i; + + for (i = 0; i < nRange; i++) { + if ((bot[i] > top[i]) || + (base < bot[i]) || + (base > top[i])) + continue; + + if (pDecode[i]) + break; + + /* Allocate decoding array */ + msk[i]++; + siz[i] = ((top[i] - bot[i] + 1UL) / msk[i]) + 1UL; + pDecode[i] = xnfalloc(siz[i]); + (void)memset(pDecode[i], -1, siz[i]); + break; + } + + return i; +} + +/* + * Verify that 'bus' is a rope's secondary bus and return the pciConfigPtr of + * the associated fake PCI-to-PCI bridge. + */ +static pciConfigPtr +VerifyZX1Bus(int bus) +{ + pciConfigPtr pPCI; + + if ((bus < 0) || (bus >= pciNumBuses) || + !pciBusInfo[bus] || !(pPCI = pciBusInfo[bus]->bridge) || + (pPCI->busnum != zx1_fakebus) || (pPCI->funcnum != 0) || + (pPCI->devnum < 0x10) || (pPCI->devnum > 0x17)) + return NULL; + + return pPCI; +} + +/* + * This function is called to emulate the various settings in a P2P or CardBus + * bridge's control register on a ZX1-based system. + */ +static CARD16 +ControlZX1Bridge(int bus, CARD16 mask, CARD16 value) +{ + pciConfigPtr pPCI; + CARD64 tmp1, tmp2, tmp3, ropenum; + CARD16 current = 0; + + if ((pPCI = VerifyZX1Bus(bus))) { + ropenum = pPCI->devnum & 0x07; + + /* + * Start with VGA enablement. This preserves the "VGA-lite" bit + * in mio's VGA_ROUTE register, and the VPE bit in each ioa's + * SLAVE_CONTROL register. + */ + tmp1 = MIO_QUAD(VGA_ROUTE); + tmp2 = IOA_QUAD(ropenum, IOA_CONTROL); + if ((tmp1 & VGA_ENABLE) && ((tmp1 & 0x07UL) == ropenum)) { + current |= PCI_PCI_BRIDGE_VGA_EN; + if ((mask & PCI_PCI_BRIDGE_VGA_EN) && + !(value & PCI_PCI_BRIDGE_VGA_EN)) { + MIO_QUAD(VGA_ROUTE) = tmp1 & ~VGA_ENABLE; + tmp2 &= ~IOA_FORWARD_VGA; + IOA_QUAD(ropenum, IOA_CONTROL) = tmp2; + } + } else if (mask & value & PCI_PCI_BRIDGE_VGA_EN) { + if (!zx1_hasvga) { + xf86MsgVerb(X_WARNING, 3, + "HP ZX1: Attempt to enable VGA routing to bus %d" + " through rope %ld disallowed\n", bus, ropenum); + value &= ~PCI_PCI_BRIDGE_VGA_EN; + } else { + if (tmp1 & VGA_ENABLE) { + /* + * VGA is routed somewhere else. Disable it. + */ + MIO_QUAD(VGA_ROUTE) = 0UL; + tmp3 = IOA_QUAD(tmp1 & 0x07UL, IOA_CONTROL); + if (tmp3 & IOA_FORWARD_VGA) + IOA_QUAD(tmp1 & 0x07UL, IOA_CONTROL) = + tmp3 & ~IOA_FORWARD_VGA; + } + if (!(tmp2 & IOA_FORWARD_VGA)) { + tmp2 |= IOA_FORWARD_VGA; + IOA_QUAD(ropenum, IOA_CONTROL) = tmp2; + } + tmp1 = (tmp1 & ~0x07UL) | ropenum | VGA_ENABLE; + MIO_QUAD(VGA_ROUTE) = tmp1; + } + } + + /* Move on to master abort failure enablement */ + tmp1 = MIO_QUAD((ropenum << 3) + LBA_PORT0_CNTRL); + if ((tmp1 & LBA_HARD_FAIL) || (tmp2 & IOA_HARD_FAIL)) { + current |= PCI_PCI_BRIDGE_MASTER_ABORT_EN; + if ((mask & PCI_PCI_BRIDGE_MASTER_ABORT_EN) && + !(value & PCI_PCI_BRIDGE_MASTER_ABORT_EN)) { + if (tmp1 & LBA_HARD_FAIL) + MIO_QUAD((ropenum << 3) + LBA_PORT0_CNTRL) = + tmp1 & ~LBA_HARD_FAIL; + if (tmp2 & IOA_HARD_FAIL) { + tmp2 &= ~IOA_HARD_FAIL; + IOA_QUAD(ropenum, IOA_CONTROL) = tmp2; + } + } + } else { + if (mask & value & PCI_PCI_BRIDGE_MASTER_ABORT_EN) { + if (!(tmp1 & LBA_HARD_FAIL)) + MIO_QUAD((ropenum << 3) + LBA_PORT0_CNTRL) = + tmp1 | LBA_HARD_FAIL; + if (!(tmp2 & IOA_HARD_FAIL)) { + tmp2 |= IOA_HARD_FAIL; + IOA_QUAD(ropenum, IOA_CONTROL) = tmp2; + } + } + } + + /* Put emulation of any other P2P bridge control here */ + } + + return (current & ~mask) | (value & mask); +} + +/* Retrieves a list of the resources routed to a rope's secondary bus */ +static void +GetZX1BridgeResources(int bus, + pointer *ppIoRes, + pointer *ppMemRes, + pointer *ppPmemRes) +{ + pciConfigPtr pPCI = VerifyZX1Bus(bus); + + if (ppIoRes) { + xf86FreeResList(*ppIoRes); + *ppIoRes = + pPCI ? xf86DupResList(pZX1IoRes[pPCI->devnum & 0x07]) : NULL; + } + + if (ppMemRes) { + xf86FreeResList(*ppMemRes); + *ppMemRes = + pPCI ? xf86DupResList(pZX1MemRes[pPCI->devnum & 0x07]) : NULL; + } + + if (ppPmemRes) { + xf86FreeResList(*ppPmemRes); + *ppPmemRes = NULL; + } +} + +/* The fake bus */ +static CARD32 +zx1FakeReadLong(PCITAG tag, int offset) +{ + FatalError("zx1FakeReadLong(0x%X, 0x%X) called\n", tag, offset); +} + +static void +zx1FakeWriteLong(PCITAG tag, int offset, CARD32 val) +{ + FatalError("zx1FakeWriteLong(0x%X, 0x%X, 0x%08X) called\n", + tag, offset, val); +} + +static void +zx1FakeSetBits(PCITAG tag, int offset, CARD32 mask, CARD32 bits) +{ + CARD32 val; + + val = zx1FakeReadLong(tag, offset); + val &= ~mask; + val |= bits; + zx1FakeWriteLong(tag, offset, val); +} + +static pciBusFuncs_t zx1FakeBusFuncs = { + zx1FakeReadLong, + zx1FakeWriteLong, + zx1FakeSetBits +}; + +static pciBusInfo_t zx1FakeBus = { + 0, /* configMech -- copied from bus 0 */ + 0, /* numDevices -- copied from bus 0 */ + FALSE, /* secondary */ + 0, /* primary_bus -- dynamically set */ +#ifdef PowerMAX_OS + 0, /* ppc_io_base -- ignored */ + 0, /* ppc_io_size -- ignored */ +#endif + &zx1FakeBusFuncs, /* funcs */ + NULL, /* pciBusPriv -- none */ + NULL, /* bridge -- dynamically set */ +}; + +/* + * This checks for, and validates, the presence of the ZX1 chipset, and sets + * pZX1mio to a non-NULL pointer accordingly. This function is called before + * the server's PCI bus scan and returns TRUE if the chipset scan is to be + * stopped, or FALSE if the scan is to move on to the next chipset. + */ +Bool +xf86PreScanZX1(void) +{ + resRange range; + unsigned long mapSize = xf86getpagesize(); + unsigned long tmp, base, ioaaddr; + unsigned long flagsd = 0, based = 0, lastd = 0, maskd = 0, routed = 0; + unsigned long flags0 = 0, base0 = 0, last0 = 0, mask0 = 0, route0 = 0; + unsigned long flags1 = 0, base1 = 0, last1 = 0, mask1 = 0, route1 = 0; + unsigned long flags2 = 0, base2 = 0, last2 = 0, mask2 = 0, route2 = 0; + unsigned long flags3 = 0, base3 = 0, last3 = 0, mask3 = 0, route3 = 0; + unsigned long flagsg = 0, baseg = 0, lastg = 0, maskg = 0, routeg = 0; + unsigned long flagsl = 0, basel = 0, lastl = 0; + int i, rope; + + /* Map mio registers (minimum 8k) */ + if (mapSize < MIO_SIZE) + mapSize = MIO_SIZE; + + if (!(pZX1mio = xf86MapVidMem(-1, VIDMEM_MMIO, MIO_BASE, mapSize))) + return FALSE; + + /* Look for ZX1's SBA and IOC */ + if ((MIO_LONG(MIO_FUNCTION0 + PCI_ID_REG) != DEVID(HP, ZX1_SBA)) || + (MIO_LONG(MIO_FUNCTION1 + PCI_ID_REG) != DEVID(HP, ZX1_IOC))) { + xf86UnMapVidMem(-1, pZX1mio, mapSize); + pZX1mio = NULL; + return FALSE; + } + + /* Map rope configuration space */ + ioaaddr = MIO_QUAD(ROPE_CONFIG_BASE); + if (!(ioaaddr & RANGE_ENABLE) || /* No ropes */ + ((ioaaddr = ioaaddr & ~RANGE_ENABLE) & 0x01FFFFUL) || /* Not aligned */ + !(pZX1ioa = xf86MapVidMem(-1, VIDMEM_MMIO, ioaaddr, IOA_SIZE))) { + xf86UnMapVidMem(-1, pZX1mio, mapSize); + pZX1mio = NULL; + return TRUE; + } + + for (i = 0; i < 8; i++) { + zx1_ropemap[i] = i; + zx1_lbacntl[i] = 0; + xf86FreeResList(pZX1IoRes[i]); + xf86FreeResList(pZX1MemRes[i]); + pZX1IoRes[i] = pZX1MemRes[i] = NULL; + } + + /* + * Determine which of 8 possible ropes exist in the system. This is done + * by looking at their "coupling" to generate a list of candidates, + * whittling this list down by factoring in ROPE_PAGE_CONTROL register + * contents, then poking each candidate's configuration space to determine + * its existence. + */ + tmp = MIO_QUAD(ROPE_CONFIG); + if (tmp & ROPE_D0) + zx1_ropemap[1] = 0; + if (tmp & ROPE_D2) + zx1_ropemap[3] = 2; + if (tmp & ROPE_D4) + zx1_ropemap[5] = 4; + if (tmp & ROPE_D6) + zx1_ropemap[7] = 6; + if (tmp & ROPE_Q0) + zx1_ropemap[1] = zx1_ropemap[2] = zx1_ropemap[3] = 0; + if (tmp & ROPE_Q4) + zx1_ropemap[5] = zx1_ropemap[6] = zx1_ropemap[7] = 4; + + tmp = MIO_QUAD(ROPE_PAGE_CONTROL); + for (i = 0; i < 8; i++, tmp >>= 8) + if (!(CARD8)tmp) + zx1_ropemap[i] = -1; + + for (i = 0; i < 8; ) { + if (zx1_ropemap[i] == i) { + + /* Prevent hard-fails */ + zx1_lbacntl[i] = MIO_QUAD((i << 3) + LBA_PORT0_CNTRL); + if (zx1_lbacntl[i] & LBA_HARD_FAIL) + MIO_QUAD((i << 3) + LBA_PORT0_CNTRL) = + zx1_lbacntl[i] & ~LBA_HARD_FAIL; + + /* Poke for an ioa */ + tmp = IOA_LONG(i, PCI_ID_REG); + switch ((CARD32)tmp) { + case DEVID(HP, ELROY): /* Expected vendor/device id's */ + case DEVID(HP, ZX1_LBA): + zx1_busno[i] = + (unsigned int)IOA_BYTE(i, IOA_SECONDARY_BUS); + zx1_subno[i] = + (unsigned int)IOA_BYTE(i, IOA_SUBORDINATE_BUS); + break; + + default: + if ((CARD16)(tmp + 1U) > (CARD16)1U) + xf86MsgVerb(X_NOTICE, 0, + "HP ZX1: Unexpected vendor/device id 0x%08X" + " on rope %d\n", (CARD32)tmp, i); + /* Nobody home, or not the "right" kind of rope guest */ + + /* + * Restore hard-fail setting. For "active" ropes, this is done + * later. + */ + if (zx1_lbacntl[i] & LBA_HARD_FAIL) { + MIO_QUAD((i << 3) + LBA_PORT0_CNTRL) = zx1_lbacntl[i]; + zx1_lbacntl[i] = 0; + } + + /* Ignore this rope and its couplings */ + do { + zx1_ropemap[i++] = -1; + } while ((i < 8) && (zx1_ropemap[i] < i)); + continue; /* Avoid over-incrementing 'i' */ + } + } + i++; + } + + /* Determine if VGA is currently routed */ + tmp = MIO_QUAD(VGA_ROUTE); + if (tmp & VGA_ENABLE) + zx1_hasvga = TRUE; + + /* + * Decode mio resource "coarse" routing (i.e. ignoring VGA). Due to the + * rather unusual flexibility of this chipset, this is done in a number of + * stages. For each of I/O and memory, first decode the relevant registers + * to generate ranges with an associated granularity. Overlapping ranges + * are merged into a larger range with the finer granularity. Each + * original range is then more thoroughly decoded using the granularity + * associated with the merged range that contains it. The result is then + * converted into resource lists for the common layer. + * + * Note that this doesn't care whether or not read-only bits are actually + * set as documented, nor that mask bits are contiguous. This does, + * however, factor in upper limits on I/O, LMMIO anf GMMIO addresses, and + * thus assumes high-order address bits are ignored rather than decoded. + * For example, an I/O address of 0x76543210 will be treated as 0x3210 + * rather than considered out-of-range. In part, this handling is a + * consequence of the fact that high-order mask bits are zeroes instead of + * ones. + */ + + if ((tmp = MIO_QUAD(IOS_DIST_BASE)) & RANGE_ENABLE) { + flagsd = RANGE_ENABLE; + maskd = MIO_QUAD(IOS_DIST_MASK); + based = tmp & maskd & (~RANGE_ENABLE & IO_MASK); + lastd = based | (~maskd & IO_MASK); + routed = MIO_QUAD(IOS_DIST_ROUTE) >> 58; + SetRange(based, lastd, routed); + } + + if ((tmp = MIO_QUAD(IOS_DIR_BASE)) & RANGE_ENABLE) { + flags0 = RANGE_ENABLE; + mask0 = MIO_QUAD(IOS_DIR_MASK); + base0 = tmp & mask0 & (~RANGE_ENABLE & IO_MASK); + last0 = base0 | (~mask0 & IO_MASK); + route0 = MIO_QUAD(IOS_DIR_ROUTE) & 0x07U; + SetRange(base0, last0, 64); + } + + if (flagsd) { + i = GetRange(based); + for (tmp = based; tmp <= lastd; tmp += msk[i]) { + if ((tmp & maskd) == based) { + base = (tmp - bot[i]) / msk[i]; + pDecode[i][base] = zx1_ropemap[(tmp >> routed) & 0x07U]; + } + } + + flagsd = 0; + } + + if (flags0) { + i = GetRange(base0); + for (tmp = base0; tmp <= last0; tmp += msk[i]) { + if ((tmp & mask0) == base0) { + base = (tmp - bot[i]) / msk[i]; + pDecode[i][base] = zx1_ropemap[route0]; + } + } + + flags0 = 0; + } + + for (i = 0; i < nRange; i++) { + if (!pDecode[i]) + continue; + + rope = pDecode[i][0]; + for (base = tmp = 0; ++tmp < siz[i]; ) { + if (rope == pDecode[i][tmp]) + continue; + + if (rope >= 0) { + RANGE(range, (base * msk[i]) + bot[i], + (tmp * msk[i]) + bot[i] - 1UL, + RANGE_TYPE(ResExcIoBlock, 0)); + pZX1IoRes[rope] = + xf86AddResToList(pZX1IoRes[rope], &range, -1); + } + + base = tmp; + rope = pDecode[i][base]; + } + + xfree(pDecode[i]); + pDecode[i] = NULL; + } + + nRange = 0; + + /* + * Move on to CPU memory access decoding. For now, don't tell the common + * layer about CPU memory ranges that are either relocated to 0 or + * translated into PCI I/O. + */ + + SetRange(MIO_BASE, MIO_BASE + MIO_SIZE - 1UL, 64); /* mio */ + SetRange(ioaaddr, ioaaddr + ((IOA_SIZE << 1) - 1UL), 64); /* ioa */ + SetRange(PDH_START, PDH_LAST, 64); /* PDH */ + + SetRange(MIO_BASE, LMMIO_MASK, 64); /* Completeness */ + + if ((tmp = MIO_QUAD(LMMIO_DIST_BASE)) & RANGE_ENABLE) { + flagsd = RANGE_ENABLE; + maskd = MIO_QUAD(LMMIO_DIST_MASK); + based = tmp & maskd & (~RANGE_ENABLE & LMMIO_MASK); + lastd = based | (~maskd & LMMIO_MASK); + routed = MIO_QUAD(LMMIO_DIST_ROUTE) >> 58; + SetRange(based, lastd, routed); + } + + if ((tmp = MIO_QUAD(LMMIO_DIR_BASE0)) & RANGE_ENABLE) { + flags0 = RANGE_ENABLE; + mask0 = MIO_QUAD(LMMIO_DIR_MASK0); + base0 = tmp & mask0 & (~RANGE_ENABLE & LMMIO_MASK); + last0 = base0 | (~mask0 & LMMIO_MASK); + route0 = MIO_QUAD(LMMIO_DIR_ROUTE0) & 0x07U; + SetRange(base0, last0, 64); + } + + if ((tmp = MIO_QUAD(LMMIO_DIR_BASE1)) & RANGE_ENABLE) { + flags1 = RANGE_ENABLE; + mask1 = MIO_QUAD(LMMIO_DIR_MASK1); + base1 = tmp & mask1 & (~RANGE_ENABLE & LMMIO_MASK); + last1 = base1 | (~mask1 & LMMIO_MASK); + route1 = MIO_QUAD(LMMIO_DIR_ROUTE1) & 0x07U; + SetRange(base1, last1, 64); + } + + if ((tmp = MIO_QUAD(LMMIO_DIR_BASE2)) & RANGE_ENABLE) { + flags2 = RANGE_ENABLE; + mask2 = MIO_QUAD(LMMIO_DIR_MASK2); + base2 = tmp & mask2 & (~RANGE_ENABLE & LMMIO_MASK); + last2 = base2 | (~mask2 & LMMIO_MASK); + route2 = MIO_QUAD(LMMIO_DIR_ROUTE2) & 0x07U; + SetRange(base2, last2, 64); + } + + if ((tmp = MIO_QUAD(LMMIO_DIR_BASE3)) & RANGE_ENABLE) { + flags3 = RANGE_ENABLE; + mask3 = MIO_QUAD(LMMIO_DIR_MASK3); + base3 = tmp & mask3 & (~RANGE_ENABLE & LMMIO_MASK); + last3 = base3 | (~mask3 & LMMIO_MASK); + route3 = MIO_QUAD(LMMIO_DIR_ROUTE3) & 0x07U; + SetRange(base3, last3, 64); + } + + if ((tmp = MIO_QUAD(GMMIO_DIST_BASE)) & RANGE_ENABLE) { + flagsg = tmp & (RANGE_ENABLE | PORT_DISABLE | MAP_TO_LMMIO); + maskg = MIO_QUAD(GMMIO_DIST_MASK); + baseg = tmp & maskg & + (~(RANGE_ENABLE | PORT_DISABLE | MAP_TO_LMMIO) & GMMIO_MASK); + lastg = baseg | (~maskg & GMMIO_MASK); + tmp = routeg = MIO_QUAD(GMMIO_DIST_ROUTE) >> 58; + if (!(flagsg & (PORT_DISABLE & MAP_TO_LMMIO)) && (tmp > 26)) + tmp = 26; + SetRange(baseg, lastg, tmp); + } + + if ((tmp = MIO_QUAD(IOS_BASE)) & RANGE_ENABLE) { + flagsl = RANGE_ENABLE; + basel = tmp & (~RANGE_ENABLE & GMMIO_MASK); + lastl = basel | 0x001FFFFFUL; + SetRange(basel, lastl, 64); + } + + if (flagsd) { + i = GetRange(based); + for (tmp = based; tmp <= lastd; tmp += msk[i]) { + if ((tmp & maskd) == based) { + base = (tmp - bot[i]) / msk[i]; + pDecode[i][base] = zx1_ropemap[(tmp >> routed) & 0x07U]; + } + } + + flagsd = 0; + } + + /* LMMIO distributed range does not address anything beyond 0xFED00000 */ + i = GetRange(MIO_BASE); + for (tmp = MIO_BASE; tmp <= LMMIO_MASK; tmp += msk[i]) { + base = (tmp - bot[i]) / msk[i]; + pDecode[i][base] = -1; + } + + /* Dillon space can sometimes be redirected to rope 0 */ + tmp = MIO_QUAD(STATUS_CONTROL); + if (!(tmp & DILLON_PRESENT)) { + i = GetRange(PDH_START); + for (tmp = PDH_START; tmp <= PDH_LAST; tmp += msk[i]) { + base = (tmp - bot[i]) / msk[i]; + pDecode[i][base] = zx1_ropemap[0]; + } + } + + if (flagsg) { + unsigned long mask = (0x07UL << routeg) | maskg; + + i = GetRange(baseg); + for (tmp = baseg; tmp <= lastg; tmp += msk[i]) { + if ((tmp & maskg) == baseg) { + base = (tmp - bot[i]) / msk[i]; + + if ((flagsg & MAP_TO_LMMIO) || + (!(flagsg & PORT_DISABLE) && + (tmp <= ((tmp & mask) | 0x03FFFFFFUL)))) { + pDecode[i][base] = -1; + } else { + pDecode[i][base] = zx1_ropemap[(tmp >> routeg) & 0x07U]; + } + } + } + + flagsg = 0; + } + + if (flagsl) { + i = GetRange(basel); + for (tmp = basel; tmp <= lastl; tmp += msk[i]) { + base = (tmp - bot[i]) / msk[i]; + pDecode[i][base] = -1; + } + + flagsl = 0; + } + + /* For now, assume directed LMMIO ranges don't overlap with each other */ + if (flags0) { + i = GetRange(base0); + for (tmp = base0; tmp <= last0; tmp += msk[i]) { + if ((tmp & mask0) == base0) { + base = (tmp - bot[i]) / msk[i]; + pDecode[i][base] = zx1_ropemap[route0]; + } + } + + flags0 = 0; + } + + if (flags1) { + i = GetRange(base1); + for (tmp = base1; tmp <= last1; tmp += msk[i]) { + if ((tmp & mask1) == base1) { + base = (tmp - bot[i]) / msk[i]; + pDecode[i][base] = zx1_ropemap[route1]; + } + } + + flags1 = 0; + } + + if (flags2) { + i = GetRange(base2); + for (tmp = base2; tmp <= last2; tmp += msk[i]) { + if ((tmp & mask2) == base2) { + base = (tmp - bot[i]) / msk[i]; + pDecode[i][base] = zx1_ropemap[route2]; + } + } + + flags2 = 0; + } + + if (flags3) { + i = GetRange(base3); + for (tmp = base3; tmp <= last3; tmp += msk[i]) { + if ((tmp & mask3) == base3) { + base = (tmp - bot[i]) / msk[i]; + pDecode[i][base] = zx1_ropemap[route3]; + } + } + + flags3 = 0; + } + + /* Claim iao config area */ + i = GetRange(ioaaddr); + for (tmp = ioaaddr; tmp < ioaaddr + (IOA_SIZE << 1); tmp += msk[i]) { + base = (tmp - bot[i]) / msk[i]; + pDecode[i][base] = -1; + } + + /* Claim mio config area */ + i = GetRange(MIO_BASE); + for (tmp = MIO_BASE; tmp < (MIO_BASE + MIO_SIZE); tmp += msk[i]) { + base = (tmp - bot[i]) / msk[i]; + pDecode[i][base] = -1; + } + + for (i = 0; i < nRange; i++) { + if (!pDecode[i]) + continue; + + rope = pDecode[i][0]; + for (base = tmp = 0; ++tmp < siz[i]; ) { + if (rope == pDecode[i][tmp]) + continue; + + if (rope >= 0) { + RANGE(range, (base * msk[i]) + bot[i], + (tmp * msk[i]) + bot[i] - 1UL, + RANGE_TYPE(ResExcMemBlock, 0)); + pZX1MemRes[rope] = + xf86AddResToList(pZX1MemRes[rope], &range, -1); + } + + base = tmp; + rope = pDecode[i][base]; + } + + xfree(pDecode[i]); + pDecode[i] = NULL; + } + + nRange = 0; + + return TRUE; +} + +/* This is called to finalise the results of a PCI bus scan */ +void +xf86PostScanZX1(void) +{ + pciConfigPtr pPCI, *ppPCI, *ppPCI2; + pciBusInfo_t *pBusInfo; + int i, idx; + + if (!pZX1mio) + return; + + /* + * Certain 2.4 & 2.5 Linux kernels add fake PCI devices. Remove them to + * prevent any possible interference with our PCI validation. + * + * Also, if VGA isn't routed on server entry, determine if VGA routing + * needs to be enabled while the server is running. + */ + idx = 0; + ppPCI = ppPCI2 = xf86scanpci(0); /* Recursion is only apparent */ + while ((pPCI = *ppPCI2++)) { + switch (pPCI->pci_device_vendor) { + case DEVID(HP, ZX1_SBA): + case DEVID(HP, ZX1_IOC): + case DEVID(HP, ZX1_LBA): + xfree(pPCI); /* Remove it */ + continue; + + default: + *ppPCI++ = pPCI; + idx++; + + if (zx1_hasvga) + continue; + + switch (pPCI->pci_base_class) { + case PCI_CLASS_PREHISTORIC: + if (pPCI->pci_sub_class == PCI_SUBCLASS_PREHISTORIC_VGA) + break; + continue; + + case PCI_CLASS_DISPLAY: + if (pPCI->pci_sub_class == PCI_SUBCLASS_DISPLAY_VGA) + break; + continue; + + default: + continue; + } + + zx1_hasvga = TRUE; + continue; + } + } + + /* + * Restore hard-fail settings and figure out the actual subordinate bus + * numbers. + */ + for (i = 0; i < 8; i++) { + if (zx1_ropemap[i] != i) + continue; + + if (zx1_lbacntl[i] & LBA_HARD_FAIL) + MIO_QUAD((i << 3) + LBA_PORT0_CNTRL) = zx1_lbacntl[i]; + + while ((zx1_busno[i] < zx1_subno[i]) && !pciBusInfo[zx1_subno[i]]) + zx1_subno[i]--; + + if (zx1_fakebus <= zx1_subno[i]) + zx1_fakebus = zx1_subno[i] + 1; + } + + if (zx1_fakebus >= pciNumBuses) { + if (zx1_fakebus >= pciMaxBusNum) + FatalError("HP ZX1: No room for fake PCI bus\n"); + pciNumBuses = zx1_fakebus + 1; + } + + /* Set up our extra bus functions */ + zx1BusFuncs = *(pciBusInfo[0]->funcs); + zx1BusFuncs.pciControlBridge = ControlZX1Bridge; + zx1BusFuncs.pciGetBridgeResources = GetZX1BridgeResources; + + /* Set up our own fake bus to act as the root segment */ + zx1FakeBus.configMech = pciBusInfo[0]->configMech; + zx1FakeBus.numDevices = pciBusInfo[0]->numDevices; + zx1FakeBus.primary_bus = zx1_fakebus; + pciBusInfo[zx1_fakebus] = &zx1FakeBus; + + /* Add the fake bus' host bridge */ + if (++idx >= MAX_PCI_DEVICES) + FatalError("HP ZX1: No room for fake Host-to-PCI bridge\n"); + *ppPCI++ = zx1FakeBus.bridge = pPCI = xnfcalloc(1, sizeof(pciDevice)); + pPCI->tag = PCI_MAKE_TAG(zx1_fakebus, 0, 0); + pPCI->busnum = zx1_fakebus; + /* pPCI->devnum = pPCI->funcnum = 0; */ + pPCI->pci_device_vendor = DEVID(HP, ZX1_SBA); + pPCI->pci_base_class = PCI_CLASS_BRIDGE; + /* pPCI->pci_sub_class = PCI_SUBCLASS_BRIDGE_HOST; */ + pPCI->fakeDevice = TRUE; + +#ifdef OLD_FORMAT + xf86MsgVerb(X_INFO, 2, "PCI: BusID 0x%.2x,0x%02x,0x%1x " + "ID 0x%04x,0x%04x Rev 0x%02x Class 0x%02x,0x%02x\n", + pPCI->busnum, pPCI->devnum, pPCI->funcnum, + pPCI->pci_vendor, pPCI->pci_device, pPCI->pci_rev_id, + pPCI->pci_base_class, pPCI->pci_sub_class); +#else + xf86MsgVerb(X_INFO, 2, "PCI: %.2x:%02x:%1x: chip %04x,%04x" + " card %04x,%04x rev %02x class %02x,%02x,%02x hdr %02x\n", + pPCI->busnum, pPCI->devnum, pPCI->funcnum, + pPCI->pci_vendor, pPCI->pci_device, + pPCI->pci_subsys_vendor, pPCI->pci_subsys_card, + pPCI->pci_rev_id, pPCI->pci_base_class, + pPCI->pci_sub_class, pPCI->pci_prog_if, + pPCI->pci_header_type); +#endif + + /* Add a fake PCI-to-PCI bridge to represent each active rope */ + for (i = 0; i < 8; i++) { + if ((zx1_ropemap[i] != i) || !(pBusInfo = pciBusInfo[zx1_busno[i]])) + continue; + + if (++idx >= MAX_PCI_DEVICES) + FatalError("HP ZX1: No room for fake PCI-to-PCI bridge\n"); + *ppPCI++ = pPCI = xnfcalloc(1, sizeof(pciDevice)); + pPCI->busnum = zx1_fakebus; + pPCI->devnum = i | 0x10; + /* pPCI->funcnum = 0; */ + pPCI->tag = PCI_MAKE_TAG(zx1_fakebus, pPCI->devnum, 0); + pPCI->pci_device_vendor = DEVID(HP, ZX1_LBA); + pPCI->pci_base_class = PCI_CLASS_BRIDGE; + pPCI->pci_sub_class = PCI_SUBCLASS_BRIDGE_PCI; + pPCI->pci_header_type = 1; + pPCI->pci_primary_bus_number = zx1_fakebus; + pPCI->pci_secondary_bus_number = zx1_busno[i]; + pPCI->pci_subordinate_bus_number = zx1_subno[i]; + pPCI->fakeDevice = TRUE; + + pBusInfo->bridge = pPCI; + pBusInfo->secondary = TRUE; + pBusInfo->primary_bus = zx1_fakebus; + + /* Plug in chipset routines */ + pBusInfo->funcs = &zx1BusFuncs; + +#ifdef OLD_FORMAT + xf86MsgVerb(X_INFO, 2, "PCI: BusID 0x%.2x,0x%02x,0x%1x " + "ID 0x%04x,0x%04x Rev 0x%02x Class 0x%02x,0x%02x\n", + pPCI->busnum, pPCI->devnum, pPCI->funcnum, + pPCI->pci_vendor, pPCI->pci_device, pPCI->pci_rev_id, + pPCI->pci_base_class, pPCI->pci_sub_class); +#else + xf86MsgVerb(X_INFO, 2, "PCI: %.2x:%02x:%1x: chip %04x,%04x" + " card %04x,%04x rev %02x class %02x,%02x,%02x hdr %02x\n", + pPCI->busnum, pPCI->devnum, pPCI->funcnum, + pPCI->pci_vendor, pPCI->pci_device, + pPCI->pci_subsys_vendor, pPCI->pci_subsys_card, + pPCI->pci_rev_id, pPCI->pci_base_class, + pPCI->pci_sub_class, pPCI->pci_prog_if, + pPCI->pci_header_type); +#endif + } + + *ppPCI = NULL; /* Terminate array */ +} diff --git a/hw/xfree86/os-support/bus/zx1PCI.h b/hw/xfree86/os-support/bus/zx1PCI.h new file mode 100644 index 000000000..b1e8a95b5 --- /dev/null +++ b/hw/xfree86/os-support/bus/zx1PCI.h @@ -0,0 +1,36 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/bus/zx1PCI.h,v 1.1 2003/02/23 20:26:49 tsi Exp $ */ +/* + * Copyright (C) 2002-2003 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ + +#ifndef PCI_ZX1_H +#define PCI_ZX1_H 1 + +#include <X11/Xdefs.h> + +Bool xf86PreScanZX1(void); +void xf86PostScanZX1(void); + +#endif diff --git a/hw/xfree86/os-support/drm/drmmodule.c b/hw/xfree86/os-support/drm/drmmodule.c new file mode 100644 index 000000000..8be822445 --- /dev/null +++ b/hw/xfree86/os-support/drm/drmmodule.c @@ -0,0 +1,56 @@ +/* drmmodule.c -- Module initialization + * Created: Fri Jun 4 09:05:48 1999 by faith@precisioninsight.com + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: Rickard E. (Rik) Faith <faith@valinux.com> + * + * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/drm/drmmodule.c,v 1.3 2000/06/17 00:03:34 martin Exp $ + * + */ + +#include "xf86Module.h" + +static MODULESETUPPROTO(drmSetup); + +static XF86ModuleVersionInfo VersRec = +{ + "drm", + MODULEVENDORSTRING, + MODINFOSTRING1, + MODINFOSTRING2, + XF86_VERSION_CURRENT, + 1, 0, 0, + ABI_CLASS_EXTENSION, + ABI_EXTENSION_VERSION, + MOD_CLASS_NONE, + {0,0,0,0} +}; + +XF86ModuleData drmModuleData = { &VersRec, drmSetup, NULL }; + +static pointer +drmSetup(pointer module, pointer opts, int *errmaj, int *errmin) +{ + return (void *)1; +} diff --git a/hw/xfree86/os-support/int10Defines.h b/hw/xfree86/os-support/int10Defines.h new file mode 100644 index 000000000..d99ea8672 --- /dev/null +++ b/hw/xfree86/os-support/int10Defines.h @@ -0,0 +1,60 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/int10Defines.h,v 1.3 2001/06/30 21:54:03 tsi Exp $ */ + +#ifndef _INT10DEFINES_H_ +#define _INT10DEFINES_H_ 1 + +#ifdef _VM86_LINUX + +#include <asm/vm86.h> + +#define CPU_R(type,name,num) \ + (((type *)&(((struct vm86_struct *)REG->cpuRegs)->regs.name))[num]) +#define CPU_RD(name,num) CPU_R(CARD32,name,num) +#define CPU_RW(name,num) CPU_R(CARD16,name,num) +#define CPU_RB(name,num) CPU_R(CARD8,name,num) + +#define X86_EAX CPU_RD(eax,0) +#define X86_EBX CPU_RD(ebx,0) +#define X86_ECX CPU_RD(ecx,0) +#define X86_EDX CPU_RD(edx,0) +#define X86_ESI CPU_RD(esi,0) +#define X86_EDI CPU_RD(edi,0) +#define X86_EBP CPU_RD(ebp,0) +#define X86_EIP CPU_RD(eip,0) +#define X86_ESP CPU_RD(esp,0) +#define X86_EFLAGS CPU_RD(eflags,0) + +#define X86_FLAGS CPU_RW(eflags,0) +#define X86_AX CPU_RW(eax,0) +#define X86_BX CPU_RW(ebx,0) +#define X86_CX CPU_RW(ecx,0) +#define X86_DX CPU_RW(edx,0) +#define X86_SI CPU_RW(esi,0) +#define X86_DI CPU_RW(edi,0) +#define X86_BP CPU_RW(ebp,0) +#define X86_IP CPU_RW(eip,0) +#define X86_SP CPU_RW(esp,0) +#define X86_CS CPU_RW(cs,0) +#define X86_DS CPU_RW(ds,0) +#define X86_ES CPU_RW(es,0) +#define X86_SS CPU_RW(ss,0) +#define X86_FS CPU_RW(fs,0) +#define X86_GS CPU_RW(gs,0) + +#define X86_AL CPU_RB(eax,0) +#define X86_BL CPU_RB(ebx,0) +#define X86_CL CPU_RB(ecx,0) +#define X86_DL CPU_RB(edx,0) + +#define X86_AH CPU_RB(eax,1) +#define X86_BH CPU_RB(ebx,1) +#define X86_CH CPU_RB(ecx,1) +#define X86_DH CPU_RB(edx,1) + +#elif defined(_X86EMU) + +#include "xf86x86emu.h" + +#endif + +#endif diff --git a/hw/xfree86/os-support/linux/int10/linux.c b/hw/xfree86/os-support/linux/int10/linux.c new file mode 100644 index 000000000..4ef765451 --- /dev/null +++ b/hw/xfree86/os-support/linux/int10/linux.c @@ -0,0 +1,627 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/int10/linux.c,v 1.29 2002/10/16 21:13:47 dawes Exp $ */ +/* + * linux specific part of the int10 module + * Copyright 1999 Egbert Eich + */ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Pci.h" +#include "compiler.h" +#define _INT10_PRIVATE +#include "xf86int10.h" +#ifdef __sparc__ +#define DEV_MEM "/dev/fb" +#else +#define DEV_MEM "/dev/mem" +#endif +#ifndef XFree86LOADER +#include <sys/mman.h> +#ifndef MAP_FAILED +#define MAP_FAILED ((void *)-1) +#endif +#endif +#define ALLOC_ENTRIES(x) ((V_RAM / x) - 1) +#define SHMERRORPTR (pointer)(-1) + +static int counter = 0; +static unsigned long int10Generation = 0; + +static CARD8 read_b(xf86Int10InfoPtr pInt, int addr); +static CARD16 read_w(xf86Int10InfoPtr pInt, int addr); +static CARD32 read_l(xf86Int10InfoPtr pInt, int addr); +static void write_b(xf86Int10InfoPtr pInt, int addr, CARD8 val); +static void write_w(xf86Int10InfoPtr pInt, int addr, CARD16 val); +static void write_l(xf86Int10InfoPtr pInt, int addr, CARD32 val); + +int10MemRec linuxMem = { + read_b, + read_w, + read_l, + write_b, + write_w, + write_l +}; + +typedef struct { + int lowMem; + int highMem; + char* base; + char* base_high; + int screen; + char* alloc; +} linuxInt10Priv; + +#if defined DoSubModules + +typedef enum { + INT10_NOT_LOADED, + INT10_LOADED_VM86, + INT10_LOADED_X86EMU, + INT10_LOAD_FAILED +} Int10LinuxSubModuleState; + +static Int10LinuxSubModuleState loadedSubModule = INT10_NOT_LOADED; + +static Int10LinuxSubModuleState int10LinuxLoadSubModule(ScrnInfoPtr pScrn); + +#endif /* DoSubModules */ + +xf86Int10InfoPtr +xf86InitInt10(int entityIndex) +{ + return xf86ExtendedInitInt10(entityIndex, 0); +} + +xf86Int10InfoPtr +xf86ExtendedInitInt10(int entityIndex, int Flags) +{ + xf86Int10InfoPtr pInt = NULL; + CARD8 *bios_base; + int screen; + int fd; + static void* vidMem = NULL; + static void* sysMem = NULL; + void* vMem = NULL; + void *options = NULL; + int low_mem; + int high_mem = -1; + char *base = SHMERRORPTR; + char *base_high = SHMERRORPTR; + int pagesize; + memType cs; + legacyVGARec vga; + xf86int10BiosLocation bios; + Bool videoBiosMapped = FALSE; + + if (int10Generation != serverGeneration) { + counter = 0; + int10Generation = serverGeneration; + } + + screen = (xf86FindScreenForEntity(entityIndex))->scrnIndex; + + options = xf86HandleInt10Options(xf86Screens[screen],entityIndex); + + if (int10skip(options)) { + xfree(options); + return NULL; + } + +#if defined DoSubModules + if (loadedSubModule == INT10_NOT_LOADED) + loadedSubModule = int10LinuxLoadSubModule(xf86Screens[screen]); + + if (loadedSubModule == INT10_LOAD_FAILED) + return NULL; +#endif + + if ((!vidMem) || (!sysMem)) { + if ((fd = open(DEV_MEM, O_RDWR, 0)) >= 0) { + if (!sysMem) { +#ifdef DEBUG + ErrorF("Mapping sys bios area\n"); +#endif + if ((sysMem = mmap((void *)(SYS_BIOS), BIOS_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_SHARED | MAP_FIXED, fd, SYS_BIOS)) + == MAP_FAILED) { + xf86DrvMsg(screen, X_ERROR, "Cannot map SYS BIOS\n"); + close(fd); + goto error0; + } + } + if (!vidMem) { +#ifdef DEBUG + ErrorF("Mapping VRAM area\n"); +#endif + if ((vidMem = mmap((void *)(V_RAM), VRAM_SIZE, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_SHARED | MAP_FIXED, fd, V_RAM)) + == MAP_FAILED) { + xf86DrvMsg(screen, X_ERROR, "Cannot map V_RAM\n"); + close(fd); + goto error0; + } + } + close(fd); + } else { + xf86DrvMsg(screen, X_ERROR, "Cannot open %s\n", DEV_MEM); + goto error0; + } + } + + pInt = (xf86Int10InfoPtr)xnfcalloc(1, sizeof(xf86Int10InfoRec)); + pInt->scrnIndex = screen; + pInt->entityIndex = entityIndex; + if (!xf86Int10ExecSetup(pInt)) + goto error0; + pInt->mem = &linuxMem; + pagesize = getpagesize(); + pInt->private = (pointer)xnfcalloc(1, sizeof(linuxInt10Priv)); + ((linuxInt10Priv*)pInt->private)->screen = screen; + ((linuxInt10Priv*)pInt->private)->alloc = + (pointer)xnfcalloc(1, ALLOC_ENTRIES(pagesize)); + + if (!xf86IsEntityPrimary(entityIndex)) { +#ifdef DEBUG + ErrorF("Mapping high memory area\n"); +#endif + if ((high_mem = shmget(counter++, HIGH_MEM_SIZE, + IPC_CREAT | SHM_R | SHM_W)) == -1) { + if (errno == ENOSYS) + xf86DrvMsg(screen, X_ERROR, "shmget error\n Please reconfigure" + " your kernel to include System V IPC support\n"); + goto error1; + } + } else { +#ifdef DEBUG + ErrorF("Mapping Video BIOS\n"); +#endif + videoBiosMapped = TRUE; + if ((fd = open(DEV_MEM, O_RDWR, 0)) >= 0) { + if ((vMem = mmap((void *)(V_BIOS), SYS_BIOS - V_BIOS, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_SHARED | MAP_FIXED, fd, V_BIOS)) + == MAP_FAILED) { + xf86DrvMsg(screen, X_ERROR, "Cannot map V_BIOS\n"); + close(fd); + goto error1; + } + close (fd); + } else + goto error1; + } + ((linuxInt10Priv*)pInt->private)->highMem = high_mem; + +#ifdef DEBUG + ErrorF("Mapping 640kB area\n"); +#endif + if ((low_mem = shmget(counter++, V_RAM, + IPC_CREAT | SHM_R | SHM_W)) == -1) + goto error2; + + ((linuxInt10Priv*)pInt->private)->lowMem = low_mem; + base = shmat(low_mem, 0, 0); + if (base == SHMERRORPTR) goto error4; + ((linuxInt10Priv *)pInt->private)->base = base; + if (high_mem > -1) { + base_high = shmat(high_mem, 0, 0); + if (base_high == SHMERRORPTR) goto error4; + ((linuxInt10Priv*)pInt->private)->base_high = base_high; + } else + ((linuxInt10Priv*)pInt->private)->base_high = NULL; + + MapCurrentInt10(pInt); + Int10Current = pInt; + +#ifdef DEBUG + ErrorF("Mapping int area\n"); +#endif + if (xf86ReadBIOS(0, 0, (unsigned char *)0, LOW_PAGE_SIZE) < 0) { + xf86DrvMsg(screen, X_ERROR, "Cannot read int vect\n"); + goto error3; + } +#ifdef DEBUG + ErrorF("done\n"); +#endif + /* + * Read in everything between V_BIOS and SYS_BIOS as some system BIOSes + * have executable code there. Note that xf86ReadBIOS() can only bring in + * 64K bytes at a time. + */ + if (!videoBiosMapped) { + (void)memset((pointer)V_BIOS, 0, SYS_BIOS - V_BIOS); +#ifdef DEBUG + ErrorF("Reading BIOS\n"); +#endif + for (cs = V_BIOS; cs < SYS_BIOS; cs += V_BIOS_SIZE) + if (xf86ReadBIOS(cs, 0, (pointer)cs, V_BIOS_SIZE) < V_BIOS_SIZE) + xf86DrvMsg(screen, X_WARNING, + "Unable to retrieve all of segment 0x%06X.\n", cs); +#ifdef DEBUG + ErrorF("done\n"); +#endif + } + + xf86int10ParseBiosLocation(options,&bios); + + if (xf86IsEntityPrimary(entityIndex) + && !(initPrimary(options))) { + if (bios.bus == BUS_ISA && bios.location.legacy) { + xf86DrvMsg(screen, X_CONFIG, + "Overriding BIOS location: 0x%lx\n", + bios.location.legacy); + cs = bios.location.legacy >> 4; + bios_base = (unsigned char *)(cs << 4); + if (!int10_check_bios(screen, cs, bios_base)) { + xf86DrvMsg(screen, X_ERROR, + "No V_BIOS at specified address 0x%x\n",cs << 4); + goto error3; + } + } else { + if (bios.bus == BUS_PCI) { + xf86DrvMsg(screen, X_WARNING, + "Option BiosLocation for primary device ignored: " + "It points to PCI.\n"); + xf86DrvMsg(screen, X_WARNING, + "You must set Option InitPrimary also\n"); + } + + cs = ((CARD16*)0)[(0x10<<1) + 1]; + + bios_base = (unsigned char *)(cs << 4); + + if (!int10_check_bios(screen, cs, bios_base)) { + cs = ((CARD16*)0)[(0x42 << 1) + 1]; + bios_base = (unsigned char *)(cs << 4); + if (!int10_check_bios(screen, cs, bios_base)) { + cs = V_BIOS >> 4; + bios_base = (unsigned char *)(cs << 4); + if (!int10_check_bios(screen, cs, bios_base)) { + xf86DrvMsg(screen, X_ERROR, "No V_BIOS found\n"); + goto error3; + } + } + } + } + + xf86DrvMsg(screen, X_INFO, "Primary V_BIOS segment is: 0x%x\n", cs); + + pInt->BIOSseg = cs; + set_return_trap(pInt); +#ifdef _PC + pInt->Flags = Flags & (SET_BIOS_SCRATCH | RESTORE_BIOS_SCRATCH); + if (! (pInt->Flags & SET_BIOS_SCRATCH)) + pInt->Flags &= ~RESTORE_BIOS_SCRATCH; + xf86Int10SaveRestoreBIOSVars(pInt, TRUE); +#endif + } else { + EntityInfoPtr pEnt = xf86GetEntityInfo(pInt->entityIndex); + BusType location_type; + + if (bios.bus != BUS_NONE) { + switch (location_type = bios.bus) { + case BUS_PCI: + xf86DrvMsg(screen,X_CONFIG,"Overriding bios location: " + "PCI:%i:%i%i\n",bios.location.pci.bus, + bios.location.pci.dev,bios.location.pci.func); + break; + case BUS_ISA: + if (bios.location.legacy) + xf86DrvMsg(screen,X_CONFIG,"Overriding bios location: " + "Legacy:0x%x\n",bios.location.legacy); + else + xf86DrvMsg(screen,X_CONFIG,"Overriding bios location: " + "Legacy\n"); + break; + default: + break; + } + } else + location_type = pEnt->location.type; + + switch (location_type) { + case BUS_PCI: + { + int pci_entity; + + if (bios.bus == BUS_PCI) + pci_entity = xf86GetPciEntity(bios.location.pci.bus, + bios.location.pci.dev, + bios.location.pci.func); + else + pci_entity = pInt->entityIndex; + if (!mapPciRom(pci_entity, (unsigned char *)(V_BIOS))) { + xf86DrvMsg(screen, X_ERROR, "Cannot read V_BIOS\n"); + goto error3; + } + pInt->BIOSseg = V_BIOS >> 4; + break; + } + case BUS_ISA: + if (bios.bus == BUS_ISA && bios.location.legacy) { + cs = bios.location.legacy >> 4; + bios_base = (unsigned char *)(cs << 4); + if (!int10_check_bios(screen, cs, bios_base)) { + xf86DrvMsg(screen,X_ERROR,"No V_BIOS found " + "on override address 0x%x\n",bios_base); + goto error3; + } + } else { + cs = ((CARD16*)0)[(0x10<<1)+1]; + bios_base = (unsigned char *)(cs << 4); + + if (!int10_check_bios(screen, cs, bios_base)) { + cs = ((CARD16*)0)[(0x42<<1)+1]; + bios_base = (unsigned char *)(cs << 4); + if (!int10_check_bios(screen, cs, bios_base)) { + cs = V_BIOS >> 4; + bios_base = (unsigned char *)(cs << 4); + if (!int10_check_bios(screen, cs, bios_base)) { + xf86DrvMsg(screen,X_ERROR,"No V_BIOS found\n"); + goto error3; + } + } + } + } + xf86DrvMsg(screen,X_INFO,"Primary V_BIOS segment is: 0x%x\n",cs); + pInt->BIOSseg = cs; + break; + default: + goto error3; + } + xfree(pEnt); + pInt->num = 0xe6; + reset_int_vect(pInt); + set_return_trap(pInt); + LockLegacyVGA(pInt, &vga); + xf86ExecX86int10(pInt); + UnlockLegacyVGA(pInt, &vga); + } +#ifdef DEBUG + dprint(0xc0000, 0x20); +#endif + + xfree(options); + return pInt; + +error4: + xf86DrvMsg(screen, X_ERROR, "shmat() call retruned errno %d\n", errno); +error3: + if (base_high) + shmdt(base_high); + shmdt(base); + shmdt(0); + if (base_high) + shmdt((char*)HIGH_MEM); + shmctl(low_mem, IPC_RMID, NULL); + Int10Current = NULL; +error2: + if (high_mem > -1) + shmctl(high_mem, IPC_RMID,NULL); +error1: + if (vMem) + munmap(vMem, SYS_BIOS - V_BIOS); + xfree(((linuxInt10Priv*)pInt->private)->alloc); + xfree(pInt->private); +error0: + xfree(options); + xfree(pInt); + return NULL; +} + +Bool +MapCurrentInt10(xf86Int10InfoPtr pInt) +{ + pointer addr; + int fd = -1; + + if (Int10Current) { + shmdt(0); + if (((linuxInt10Priv*)Int10Current->private)->highMem >= 0) + shmdt((char*)HIGH_MEM); + else + munmap((pointer)V_BIOS, (SYS_BIOS - V_BIOS)); + } + addr = shmat(((linuxInt10Priv*)pInt->private)->lowMem, (char*)1, SHM_RND); + if (addr == SHMERRORPTR) { + xf86DrvMsg(pInt->scrnIndex, X_ERROR, "Cannot shmat() low memory\n"); + return FALSE; + } + + if (((linuxInt10Priv*)pInt->private)->highMem >= 0) { + addr = shmat(((linuxInt10Priv*)pInt->private)->highMem, + (char*)HIGH_MEM, 0); + if (addr == SHMERRORPTR) { + xf86DrvMsg(pInt->scrnIndex, X_ERROR, + "Cannot shmat() high memory\n"); + return FALSE; + } + } else { + if ((fd = open(DEV_MEM, O_RDWR, 0)) >= 0) { + if (mmap((void *)(V_BIOS), SYS_BIOS - V_BIOS, + PROT_READ | PROT_WRITE | PROT_EXEC, + MAP_SHARED | MAP_FIXED, fd, V_BIOS) + == MAP_FAILED) { + xf86DrvMsg(pInt->scrnIndex, X_ERROR, "Cannot map V_BIOS\n"); + close (fd); + return FALSE; + } + } else { + xf86DrvMsg(pInt->scrnIndex, X_ERROR, "Cannot open %s\n",DEV_MEM); + return FALSE; + } + close (fd); + } + + return TRUE; +} + +void +xf86FreeInt10(xf86Int10InfoPtr pInt) +{ + if (!pInt) + return; + +#ifdef _PC + xf86Int10SaveRestoreBIOSVars(pInt, FALSE); +#endif + if (Int10Current == pInt) { + shmdt(0); + if (((linuxInt10Priv*)pInt->private)->highMem >= 0) + shmdt((char*)HIGH_MEM); + else + munmap((pointer)V_BIOS, (SYS_BIOS - V_BIOS)); + Int10Current = NULL; + } + + if (((linuxInt10Priv*)pInt->private)->base_high) + shmdt(((linuxInt10Priv*)pInt->private)->base_high); + shmdt(((linuxInt10Priv*)pInt->private)->base); + shmctl(((linuxInt10Priv*)pInt->private)->lowMem, IPC_RMID, NULL); + if (((linuxInt10Priv*)pInt->private)->highMem >= 0) + shmctl(((linuxInt10Priv*)pInt->private)->highMem, IPC_RMID, NULL); + xfree(((linuxInt10Priv*)pInt->private)->alloc); + xfree(pInt->private); + xfree(pInt); +} + +void * +xf86Int10AllocPages(xf86Int10InfoPtr pInt, int num, int *off) +{ + int pagesize = getpagesize(); + int num_pages = ALLOC_ENTRIES(pagesize); + int i, j; + + for (i = 0; i < (num_pages - num); i++) { + if (((linuxInt10Priv*)pInt->private)->alloc[i] == 0) { + for (j = i; j < (num + i); j++) + if ((((linuxInt10Priv*)pInt->private)->alloc[j] != 0)) + break; + if (j == (num + i)) + break; + else + i = i + num; + } + } + if (i == (num_pages - num)) + return NULL; + + for (j = i; j < (i + num); j++) + ((linuxInt10Priv*)pInt->private)->alloc[j] = 1; + + *off = (i + 1) * pagesize; + + return ((linuxInt10Priv*)pInt->private)->base + ((i + 1) * pagesize); +} + +void +xf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase, int num) +{ + int pagesize = getpagesize(); + int first = (((unsigned long)pbase + - (unsigned long)((linuxInt10Priv*)pInt->private)->base) + / pagesize) - 1; + int i; + + for (i = first; i < (first + num); i++) + ((linuxInt10Priv*)pInt->private)->alloc[i] = 0; +} + +static CARD8 +read_b(xf86Int10InfoPtr pInt, int addr) +{ + return *((CARD8 *)(memType)addr); +} + +static CARD16 +read_w(xf86Int10InfoPtr pInt, int addr) +{ + return *((CARD16 *)(memType)addr); +} + +static CARD32 +read_l(xf86Int10InfoPtr pInt, int addr) +{ + return *((CARD32 *)(memType)addr); +} + +static void +write_b(xf86Int10InfoPtr pInt, int addr, CARD8 val) +{ + *((CARD8 *)(memType)addr) = val; +} + +static void +write_w(xf86Int10InfoPtr pInt, int addr, CARD16 val) +{ + *((CARD16 *)(memType)addr) = val; +} + +static +void write_l(xf86Int10InfoPtr pInt, int addr, CARD32 val) +{ + *((CARD32 *)(memType) addr) = val; +} + +pointer +xf86int10Addr(xf86Int10InfoPtr pInt, CARD32 addr) +{ + if (addr < V_RAM) + return ((linuxInt10Priv*)pInt->private)->base + addr; + else if (addr < V_BIOS) + return (pointer)(memType)addr; + else if (addr < SYS_BIOS) { + if (((linuxInt10Priv*)pInt->private)->base_high) + return (pointer)(((linuxInt10Priv*)pInt->private)->base_high + - V_BIOS + addr); + else + return (pointer) (memType)addr; + } else + return (pointer) (memType)addr; +} + +#if defined DoSubModules + +static Bool +vm86_tst(void) +{ + int __res; + +#ifdef __PIC__ + /* When compiling with -fPIC, we can't use asm constraint "b" because + %ebx is already taken by gcc. */ + __asm__ __volatile__("pushl %%ebx\n\t" + "movl %2,%%ebx\n\t" + "movl %1,%%eax\n\t" + "int $0x80\n\t" + "popl %%ebx" + :"=a" (__res) + :"n" ((int)113), "r" (NULL)); +#else + __asm__ __volatile__("int $0x80\n\t" + :"=a" (__res):"a" ((int)113), + "b" ((struct vm86_struct *)NULL)); +#endif + + if (__res < 0 && __res == -ENOSYS) + return FALSE; + + return TRUE; +} + +static Int10LinuxSubModuleState +int10LinuxLoadSubModule(ScrnInfoPtr pScrn) +{ + if (vm86_tst()) { + if (xf86LoadSubModule(pScrn,"vm86")) + return INT10_LOADED_VM86; + } + if (xf86LoadSubModule(pScrn,"x86emu")) + return INT10_LOADED_X86EMU; + + return INT10_LOAD_FAILED; +} + +#endif /* DoSubModules */ diff --git a/hw/xfree86/os-support/linux/int10/vm86/linux_vm86.c b/hw/xfree86/os-support/linux/int10/vm86/linux_vm86.c new file mode 100644 index 000000000..6203cc3c3 --- /dev/null +++ b/hw/xfree86/os-support/linux/int10/vm86/linux_vm86.c @@ -0,0 +1,292 @@ +#include "xf86.h" +#include "xf86_OSproc.h" +#include "xf86_ansic.h" +#include "xf86Pci.h" +#include "compiler.h" +#define _INT10_PRIVATE +#include "xf86int10.h" + +#define REG pInt + +#ifdef _VM86_LINUX +#include "int10Defines.h" + +static int vm86_rep(struct vm86_struct *ptr); +static struct vm86_struct vm86_s; + +Bool +xf86Int10ExecSetup(xf86Int10InfoPtr pInt) +{ +#define VM86S ((struct vm86_struct *)pInt->cpuRegs) + + pInt->cpuRegs = &vm86_s; + VM86S->flags = 0; + VM86S->screen_bitmap = 0; + VM86S->cpu_type = CPU_586; + memset(&VM86S->int_revectored, 0xff, sizeof(VM86S->int_revectored)); + memset(&VM86S->int21_revectored, 0xff, sizeof(VM86S->int21_revectored)); + return TRUE; +} + +/* get the linear address */ +#define LIN_PREF_SI ((pref_seg << 4) + X86_SI) +#define LWECX ((prefix66 ^ prefix67) ? X86_ECX : X86_CX) +#define LWECX_ZERO {if (prefix66 ^ prefix67) X86_ECX = 0; else X86_CX = 0;} +#define DF (1 << 10) + +/* vm86 fault handling */ +static Bool +vm86_GP_fault(xf86Int10InfoPtr pInt) +{ + unsigned char *csp, *lina; + CARD32 org_eip; + int pref_seg; + int done, is_rep, prefix66, prefix67; + + csp = lina = SEG_ADR((unsigned char *), X86_CS, IP); + + is_rep = 0; + prefix66 = prefix67 = 0; + pref_seg = -1; + + /* eat up prefixes */ + done = 0; + do { + switch (MEM_RB(pInt, (int)csp++)) { + case 0x66: /* operand prefix */ prefix66=1; break; + case 0x67: /* address prefix */ prefix67=1; break; + case 0x2e: /* CS */ pref_seg=X86_CS; break; + case 0x3e: /* DS */ pref_seg=X86_DS; break; + case 0x26: /* ES */ pref_seg=X86_ES; break; + case 0x36: /* SS */ pref_seg=X86_SS; break; + case 0x65: /* GS */ pref_seg=X86_GS; break; + case 0x64: /* FS */ pref_seg=X86_FS; break; + case 0xf0: /* lock */ break; + case 0xf2: /* repnz */ + case 0xf3: /* rep */ is_rep=1; break; + default: done=1; + } + } while (!done); + csp--; /* oops one too many */ + org_eip = X86_EIP; + X86_IP += (csp - lina); + + switch (MEM_RB(pInt, (int)csp)) { + case 0x6c: /* insb */ + /* NOTE: ES can't be overwritten; prefixes 66,67 should use esi,edi,ecx + * but is anyone using extended regs in real mode? */ + /* WARNING: no test for DI wrapping! */ + X86_EDI += port_rep_inb(pInt, X86_DX, SEG_EADR((CARD32), X86_ES, DI), + X86_FLAGS & DF, is_rep ? LWECX : 1); + if (is_rep) LWECX_ZERO; + X86_IP++; + break; + + case 0x6d: /* (rep) insw / insd */ + /* NOTE: ES can't be overwritten */ + /* WARNING: no test for _DI wrapping! */ + if (prefix66) { + X86_DI += port_rep_inl(pInt, X86_DX, SEG_ADR((CARD32), X86_ES, DI), + X86_EFLAGS & DF, is_rep ? LWECX : 1); + } + else { + X86_DI += port_rep_inw(pInt, X86_DX, SEG_ADR((CARD32), X86_ES, DI), + X86_FLAGS & DF, is_rep ? LWECX : 1); + } + if (is_rep) LWECX_ZERO; + X86_IP++; + break; + + case 0x6e: /* (rep) outsb */ + if (pref_seg < 0) pref_seg = X86_DS; + /* WARNING: no test for _SI wrapping! */ + X86_SI += port_rep_outb(pInt, X86_DX, (CARD32)LIN_PREF_SI, + X86_FLAGS & DF, is_rep ? LWECX : 1); + if (is_rep) LWECX_ZERO; + X86_IP++; + break; + + case 0x6f: /* (rep) outsw / outsd */ + if (pref_seg < 0) pref_seg = X86_DS; + /* WARNING: no test for _SI wrapping! */ + if (prefix66) { + X86_SI += port_rep_outl(pInt, X86_DX, (CARD32)LIN_PREF_SI, + X86_EFLAGS & DF, is_rep ? LWECX : 1); + } + else { + X86_SI += port_rep_outw(pInt, X86_DX, (CARD32)LIN_PREF_SI, + X86_FLAGS & DF, is_rep ? LWECX : 1); + } + if (is_rep) LWECX_ZERO; + X86_IP++; + break; + + case 0xe5: /* inw xx, inl xx */ + if (prefix66) X86_EAX = x_inl(csp[1]); + else X86_AX = x_inw(csp[1]); + X86_IP += 2; + break; + + case 0xe4: /* inb xx */ + X86_AL = x_inb(csp[1]); + X86_IP += 2; + break; + + case 0xed: /* inw dx, inl dx */ + if (prefix66) X86_EAX = x_inl(X86_DX); + else X86_AX = x_inw(X86_DX); + X86_IP += 1; + break; + + case 0xec: /* inb dx */ + X86_AL = x_inb(X86_DX); + X86_IP += 1; + break; + + case 0xe7: /* outw xx */ + if (prefix66) x_outl(csp[1], X86_EAX); + else x_outw(csp[1], X86_AX); + X86_IP += 2; + break; + + case 0xe6: /* outb xx */ + x_outb(csp[1], X86_AL); + X86_IP += 2; + break; + + case 0xef: /* outw dx */ + if (prefix66) x_outl(X86_DX, X86_EAX); + else x_outw(X86_DX, X86_AX); + X86_IP += 1; + break; + + case 0xee: /* outb dx */ + x_outb(X86_DX, X86_AL); + X86_IP += 1; + break; + + case 0xf4: +#ifdef DEBUG + ErrorF("hlt at %p\n", lina); +#endif + return FALSE; + + case 0x0f: + xf86DrvMsg(pInt->scrnIndex, X_ERROR, + "CPU 0x0f Trap at CS:EIP=0x%4.4x:0x%8.8x\n", X86_CS, X86_EIP); + goto op0ferr; + + default: + xf86DrvMsg(pInt->scrnIndex, X_ERROR, "unknown reason for exception\n"); + + op0ferr: + dump_registers(pInt); + stack_trace(pInt); + dump_code(pInt); + xf86DrvMsg(pInt->scrnIndex, X_ERROR, "cannot continue\n"); + return FALSE; + } /* end of switch() */ + return TRUE; +} + +static int +do_vm86(xf86Int10InfoPtr pInt) +{ + int retval, signo; + + xf86InterceptSignals(&signo); + retval = vm86_rep(VM86S); + xf86InterceptSignals(NULL); + + if (signo >= 0) { + xf86DrvMsg(pInt->scrnIndex, X_ERROR, + "vm86() syscall generated signal %d.\n", signo); + dump_registers(pInt); + dump_code(pInt); + stack_trace(pInt); + return 0; + } + + switch (VM86_TYPE(retval)) { + case VM86_UNKNOWN: + if (!vm86_GP_fault(pInt)) return 0; + break; + case VM86_STI: + xf86DrvMsg(pInt->scrnIndex, X_ERROR, "vm86_sti :-((\n"); + dump_registers(pInt); + dump_code(pInt); + stack_trace(pInt); + return 0; + case VM86_INTx: + pInt->num = VM86_ARG(retval); + if (!int_handler(pInt)) { + xf86DrvMsg(pInt->scrnIndex, X_ERROR, + "Unknown vm86_int: 0x%X\n\n", VM86_ARG(retval)); + dump_registers(pInt); + dump_code(pInt); + stack_trace(pInt); + return 0; + } + /* I'm not sure yet what to do if we can handle ints */ + break; + case VM86_SIGNAL: + return 1; + /* + * we used to warn here and bail out - but now the sigio stuff + * always fires signals at us. So we just ignore them for now. + */ + xf86DrvMsg(pInt->scrnIndex, X_WARNING, "received signal\n"); + return 0; + default: + xf86DrvMsg(pInt->scrnIndex, X_ERROR, "unknown type(0x%x)=0x%x\n", + VM86_ARG(retval), VM86_TYPE(retval)); + dump_registers(pInt); + dump_code(pInt); + stack_trace(pInt); + return 0; + } + + return 1; +} + +void +xf86ExecX86int10(xf86Int10InfoPtr pInt) +{ + int sig = setup_int(pInt); + + if (int_handler(pInt)) + while(do_vm86(pInt)) {}; + + finish_int(pInt, sig); +} + +static int +vm86_rep(struct vm86_struct *ptr) +{ + int __res; + +#ifdef __PIC__ + /* When compiling with -fPIC, we can't use asm constraint "b" because + %ebx is already taken by gcc. */ + __asm__ __volatile__("pushl %%ebx\n\t" + "movl %2,%%ebx\n\t" + "movl %1,%%eax\n\t" + "int $0x80\n\t" + "popl %%ebx" + :"=a" (__res) + :"n" ((int)113), "r" ((struct vm86_struct *)ptr)); +#else + __asm__ __volatile__("int $0x80\n\t" + :"=a" (__res):"a" ((int)113), + "b" ((struct vm86_struct *)ptr)); +#endif + + if (__res < 0) { + errno = -__res; + __res = -1; + } + else errno = 0; + return __res; +} + +#endif diff --git a/hw/xfree86/os-support/linux/lnx.h b/hw/xfree86/os-support/linux/lnx.h new file mode 100644 index 000000000..f2dd16267 --- /dev/null +++ b/hw/xfree86/os-support/linux/lnx.h @@ -0,0 +1,44 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx.h,v 3.3 2002/11/25 14:05:04 eich Exp $ */ + +#ifndef LNX_H_ +# ifdef __alpha__ +extern unsigned long _bus_base __P ((void)) __attribute__ ((const)); +extern unsigned long _bus_base_sparse __P ((void)) __attribute__ ((const)); +extern int iopl __P ((int __level)); + +/* new pciconfig_iobase syscall added in 2.2.15 and 2.3.99 */ +# include <linux/unistd.h> +# include <asm/pci.h> +extern long (*_iobase)(unsigned, int, int, int); + +/* + * _iobase deals with the case the __NR_pciconfig_iobase is either undefined + * or unsupported by the kernel, but we need to make sure that the `which' + * argument symbols are defined. + */ +# ifndef IOBASE_HOSE +# define IOBASE_HOSE 0 +# endif +# ifndef IOBASE_SPARSE_MEM +# define IOBASE_SPARSE_MEM 1 +# endif +# ifndef IOBASE_DENSE_MEM +# define IOBASE_DENSE_MEM 2 +# endif +# ifndef IOBASE_SPARSE_IO +# define IOBASE_SPARSE_IO 3 +# endif +# ifndef IOBASE_DENSE_IO +# define IOBASE_DENSE_IO 4 +# endif +# ifndef IOBASE_ROOT_BUS +# define IOBASE_ROOT_BUS 5 +# endif +# ifndef IOBASE_FROM_HOSE +# define IOBASE_FROM_HOSE 0x10000 +# endif +# endif /* __alpha__ */ + +#define LNX_H_ + +#endif diff --git a/hw/xfree86/os-support/linux/lnxResource.c b/hw/xfree86/os-support/linux/lnxResource.c new file mode 100644 index 000000000..04e2f07c0 --- /dev/null +++ b/hw/xfree86/os-support/linux/lnxResource.c @@ -0,0 +1,286 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnxResource.c,v 3.18 2002/01/25 21:56:19 tsi Exp $ */ + +/* Resource information code */ + +#include "X.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86Privstr.h" +#include "xf86Pci.h" +#include "xf86Resources.h" +#define NEED_OS_RAC_PROTOS +#include "xf86_OSlib.h" +#include "lnx.h" + +/* Avoid Imakefile changes */ +#include "bus/Pci.h" + +resRange PciAvoid[] = +{ +#if !defined(__sparc__) || !defined(INCLUDE_XF86_NO_DOMAIN) + _PCI_AVOID_PC_STYLE, +#endif + _END +}; + +#ifdef INCLUDE_XF86_NO_DOMAIN + +#ifdef __alpha__ + +resPtr +xf86BusAccWindowsFromOS(void) +{ + resPtr ret = NULL; + resRange range; + + RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + + RANGE(range, 0x00000000, 0xffffffff, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); + return ret; +} + +resPtr +xf86PciBusAccWindowsFromOS(void) +{ + resPtr ret = NULL; + resRange range; + /* + * On the Alpha the first 16MB of every 128 Mb segment in + * sparse address space are an image of the ISA bus range + */ + if (_bus_base_sparse()) { + RANGE(range, 0x00000000, 0x07ffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x09000000, 0x0fffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x11000000, 0x17ffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x19000000, 0x1fffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x21000000, 0x27ffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x29000000, 0x2fffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x31000000, 0x37ffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x39000000, 0x3fffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x41000000, 0x47ffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x49000000, 0x4fffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x51000000, 0x57ffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x59000000, 0x5fffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x61000000, 0x67ffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x69000000, 0x6fffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x71000000, 0x77ffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x79000000, 0x7fffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x81000000, 0x87ffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x89000000, 0x8fffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x91000000, 0x97ffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x99000000, 0x9fffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0xa1000000, 0xa7ffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0xa9000000, 0xafffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0xb1000000, 0xb7ffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0xb9000000, 0xbfffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0xc1000000, 0xc7ffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0xc9000000, 0xcfffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0xd1000000, 0xd7ffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0xd9000000, 0xdfffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0xe1000000, 0xe7ffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0xe9000000, 0xefffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0xf1000000, 0xf7ffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0xf9000000, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + } else { + RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + } + RANGE(range, 0x00000000, 0xffffffff, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); + return ret; +} + +#ifdef INCLUDE_UNUSED + +resPtr +xf86IsaBusAccWindowsFromOS(void) +{ + resPtr ret = NULL; + resRange range; + + RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + + RANGE(range, 0x00000000, 0xffffffff, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); + return ret; +} + +#endif /* INCLUDE_UNUSED */ + +resPtr +xf86AccResFromOS(resPtr ret) +{ + resRange range; + + /* + * Fallback is to claim the following areas: + * + * 0x000c0000 - 0x000effff location of VGA and other extensions ROMS + */ + + RANGE(range, 0x000c0000, 0x000effff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + + /* + * Fallback would be to claim well known ports in the 0x0 - 0x3ff range + * along with their sparse I/O aliases, but that's too imprecise. Instead + * claim a bare minimum here. + */ + RANGE(range, 0x00000000, 0x000000ff, ResExcIoBlock); /* For mainboard */ + ret = xf86AddResToList(ret, &range, -1); + + /* + * At minimum, the top and bottom resources must be claimed, so that + * resources that are (or appear to be) unallocated can be relocated. + */ + RANGE(range, 0x00000000, 0x00000000, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0xffffffff, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); +/* RANGE(range, 0x00000000, 0x00000000, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); */ + RANGE(range, 0xffffffff, 0xffffffff, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); + + /* XXX add others */ + return ret; +} + +#elif defined(__powerpc__) || \ + defined(__sparc__) || \ + defined(__mips__) || \ + defined(__sh__) || \ + defined(__mc68000__) || \ + defined(__arm__) || \ + defined(__s390__) || \ + defined(__hppa__) + + /* XXX this isn't exactly correct but it will get the server working + * for now until we get something better. + */ + +resPtr +xf86BusAccWindowsFromOS(void) +{ + resPtr ret = NULL; + resRange range; + + RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + +#ifdef __sparc__ + RANGE(range, 0x00000000, 0x00ffffff, ResExcIoBlock); +#else + RANGE(range, 0x00000000, 0x0000ffff, ResExcIoBlock); +#endif + ret = xf86AddResToList(ret, &range, -1); + return ret; +} + +resPtr +xf86PciBusAccWindowsFromOS(void) +{ + resPtr ret = NULL; + resRange range; + + RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + +#ifdef __sparc__ + RANGE(range, 0x00000000, 0x00ffffff, ResExcIoBlock); +#else + RANGE(range, 0x00000000, 0x0000ffff, ResExcIoBlock); +#endif + ret = xf86AddResToList(ret, &range, -1); + return ret; +} + +#ifdef INCLUDE_UNUSED */ + +resPtr +xf86IsaBusAccWindowsFromOS(void) +{ + resPtr ret = NULL; + resRange range; + + RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + +#ifdef __sparc__ + RANGE(range, 0x00000000, 0x00ffffff, ResExcIoBlock); +#else + RANGE(range, 0x00000000, 0x0000ffff, ResExcIoBlock); +#endif + ret = xf86AddResToList(ret, &range, -1); + return ret; +} + +#endif /* INCLUDE_UNUSED */ + +resPtr +xf86AccResFromOS(resPtr ret) +{ + resRange range; + + /* + * At minimum, the top and bottom resources must be claimed, so that + * resources that are (or appear to be) unallocated can be relocated. + */ + RANGE(range, 0x00000000, 0x00000000, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0xffffffff, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x00000000, 0x00000000, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); +#ifdef __sparc__ + RANGE(range, 0x00ffffff, 0x00ffffff, ResExcIoBlock); +#else + RANGE(range, 0x0000ffff, 0x0000ffff, ResExcIoBlock); +#endif + ret = xf86AddResToList(ret, &range, -1); + + return ret; +} + +#else + +#error : Put your platform dependent code here!! + +#endif + +#endif /* INCLUDE_XF86_NO_DOMAIN */ diff --git a/hw/xfree86/os-support/linux/lnx_KbdMap.c b/hw/xfree86/os-support/linux/lnx_KbdMap.c new file mode 100644 index 000000000..25639d72d --- /dev/null +++ b/hw/xfree86/os-support/linux/lnx_KbdMap.c @@ -0,0 +1,603 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_KbdMap.c,v 1.1 2002/10/11 01:40:35 dawes Exp $ */ + +/* + * Slightly modified xf86KbdLnx.c which is + * + * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany. + */ + +#include "X.h" +#include "Xmd.h" +#include "input.h" +#include "scrnintstr.h" + +#include "compiler.h" + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "xf86Xinput.h" +#include "xf86OSKbd.h" +#include "atKeynames.h" + +#include "xf86Keymap.h" +#include "DECkeysym.h" + +#include "lnx_kbd.h" + +/*ARGSUSED*/ + +/* + * KbdGetMapping -- + * Get the national keyboard mapping. The keyboard type is set, a new map + * and the modifiermap is computed. + */ + +static void readKernelMapping(InputInfoPtr pInfo, + KeySymsPtr pKeySyms, CARD8 *pModMap); +void +KbdGetMapping (InputInfoPtr pInfo, KeySymsPtr pKeySyms, CARD8 *pModMap) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + KeySym *k; + char type; + int i; + + readKernelMapping(pInfo, pKeySyms, pModMap); + + /* + * compute the modifier map + */ + for (i = 0; i < MAP_LENGTH; i++) + pModMap[i] = NoSymbol; /* make sure it is restored */ + + for (k = map, i = MIN_KEYCODE; + i < (NUM_KEYCODES + MIN_KEYCODE); + i++, k += 4) + + switch(*k) { + + case XK_Shift_L: + case XK_Shift_R: + pModMap[i] = ShiftMask; + break; + + case XK_Control_L: + case XK_Control_R: + pModMap[i] = ControlMask; + break; + + case XK_Caps_Lock: + pModMap[i] = LockMask; + break; + + case XK_Alt_L: + case XK_Alt_R: + pModMap[i] = AltMask; + break; + + case XK_Num_Lock: + pModMap[i] = NumLockMask; + break; + + case XK_Scroll_Lock: + pModMap[i] = ScrollLockMask; + break; + + /* kana support */ + case XK_Kana_Lock: + case XK_Kana_Shift: + pModMap[i] = KanaMask; + break; + + /* alternate toggle for multinational support */ + case XK_Mode_switch: + pModMap[i] = AltLangMask; + break; + + } + + pKbd->kbdType = ioctl(pInfo->fd, KDGKBTYPE, &type) != -1 ? type : KB_101; + + pKeySyms->map = map; + pKeySyms->mapWidth = GLYPHS_PER_KEY; + pKeySyms->minKeyCode = MIN_KEYCODE; + pKeySyms->maxKeyCode = MAX_KEYCODE; +} + +#include <linux/keyboard.h> + +static KeySym linux_to_x[256] = { + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + XK_BackSpace, XK_Tab, XK_Linefeed, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, XK_Escape, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + XK_space, XK_exclam, XK_quotedbl, XK_numbersign, + XK_dollar, XK_percent, XK_ampersand, XK_apostrophe, + XK_parenleft, XK_parenright, XK_asterisk, XK_plus, + XK_comma, XK_minus, XK_period, XK_slash, + XK_0, XK_1, XK_2, XK_3, + XK_4, XK_5, XK_6, XK_7, + XK_8, XK_9, XK_colon, XK_semicolon, + XK_less, XK_equal, XK_greater, XK_question, + XK_at, XK_A, XK_B, XK_C, + XK_D, XK_E, XK_F, XK_G, + XK_H, XK_I, XK_J, XK_K, + XK_L, XK_M, XK_N, XK_O, + XK_P, XK_Q, XK_R, XK_S, + XK_T, XK_U, XK_V, XK_W, + XK_X, XK_Y, XK_Z, XK_bracketleft, + XK_backslash, XK_bracketright,XK_asciicircum, XK_underscore, + XK_grave, XK_a, XK_b, XK_c, + XK_d, XK_e, XK_f, XK_g, + XK_h, XK_i, XK_j, XK_k, + XK_l, XK_m, XK_n, XK_o, + XK_p, XK_q, XK_r, XK_s, + XK_t, XK_u, XK_v, XK_w, + XK_x, XK_y, XK_z, XK_braceleft, + XK_bar, XK_braceright, XK_asciitilde, XK_BackSpace, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + NoSymbol, NoSymbol, NoSymbol, NoSymbol, + XK_nobreakspace,XK_exclamdown, XK_cent, XK_sterling, + XK_currency, XK_yen, XK_brokenbar, XK_section, + XK_diaeresis, XK_copyright, XK_ordfeminine, XK_guillemotleft, + XK_notsign, XK_hyphen, XK_registered, XK_macron, + XK_degree, XK_plusminus, XK_twosuperior, XK_threesuperior, + XK_acute, XK_mu, XK_paragraph, XK_periodcentered, + XK_cedilla, XK_onesuperior, XK_masculine, XK_guillemotright, + XK_onequarter, XK_onehalf, XK_threequarters,XK_questiondown, + XK_Agrave, XK_Aacute, XK_Acircumflex, XK_Atilde, + XK_Adiaeresis, XK_Aring, XK_AE, XK_Ccedilla, + XK_Egrave, XK_Eacute, XK_Ecircumflex, XK_Ediaeresis, + XK_Igrave, XK_Iacute, XK_Icircumflex, XK_Idiaeresis, + XK_ETH, XK_Ntilde, XK_Ograve, XK_Oacute, + XK_Ocircumflex, XK_Otilde, XK_Odiaeresis, XK_multiply, + XK_Ooblique, XK_Ugrave, XK_Uacute, XK_Ucircumflex, + XK_Udiaeresis, XK_Yacute, XK_THORN, XK_ssharp, + XK_agrave, XK_aacute, XK_acircumflex, XK_atilde, + XK_adiaeresis, XK_aring, XK_ae, XK_ccedilla, + XK_egrave, XK_eacute, XK_ecircumflex, XK_ediaeresis, + XK_igrave, XK_iacute, XK_icircumflex, XK_idiaeresis, + XK_eth, XK_ntilde, XK_ograve, XK_oacute, + XK_ocircumflex, XK_otilde, XK_odiaeresis, XK_division, + XK_oslash, XK_ugrave, XK_uacute, XK_ucircumflex, + XK_udiaeresis, XK_yacute, XK_thorn, XK_ydiaeresis +}; + +/* + * Maps the AT keycodes to Linux keycodes + */ +static unsigned char at2lnx[NUM_KEYCODES] = +{ + 0x01, /* KEY_Escape */ 0x02, /* KEY_1 */ + 0x03, /* KEY_2 */ 0x04, /* KEY_3 */ + 0x05, /* KEY_4 */ 0x06, /* KEY_5 */ + 0x07, /* KEY_6 */ 0x08, /* KEY_7 */ + 0x09, /* KEY_8 */ 0x0a, /* KEY_9 */ + 0x0b, /* KEY_0 */ 0x0c, /* KEY_Minus */ + 0x0d, /* KEY_Equal */ 0x0e, /* KEY_BackSpace */ + 0x0f, /* KEY_Tab */ 0x10, /* KEY_Q */ + 0x11, /* KEY_W */ 0x12, /* KEY_E */ + 0x13, /* KEY_R */ 0x14, /* KEY_T */ + 0x15, /* KEY_Y */ 0x16, /* KEY_U */ + 0x17, /* KEY_I */ 0x18, /* KEY_O */ + 0x19, /* KEY_P */ 0x1a, /* KEY_LBrace */ + 0x1b, /* KEY_RBrace */ 0x1c, /* KEY_Enter */ + 0x1d, /* KEY_LCtrl */ 0x1e, /* KEY_A */ + 0x1f, /* KEY_S */ 0x20, /* KEY_D */ + 0x21, /* KEY_F */ 0x22, /* KEY_G */ + 0x23, /* KEY_H */ 0x24, /* KEY_J */ + 0x25, /* KEY_K */ 0x26, /* KEY_L */ + 0x27, /* KEY_SemiColon */ 0x28, /* KEY_Quote */ + 0x29, /* KEY_Tilde */ 0x2a, /* KEY_ShiftL */ + 0x2b, /* KEY_BSlash */ 0x2c, /* KEY_Z */ + 0x2d, /* KEY_X */ 0x2e, /* KEY_C */ + 0x2f, /* KEY_V */ 0x30, /* KEY_B */ + 0x31, /* KEY_N */ 0x32, /* KEY_M */ + 0x33, /* KEY_Comma */ 0x34, /* KEY_Period */ + 0x35, /* KEY_Slash */ 0x36, /* KEY_ShiftR */ + 0x37, /* KEY_KP_Multiply */ 0x38, /* KEY_Alt */ + 0x39, /* KEY_Space */ 0x3a, /* KEY_CapsLock */ + 0x3b, /* KEY_F1 */ 0x3c, /* KEY_F2 */ + 0x3d, /* KEY_F3 */ 0x3e, /* KEY_F4 */ + 0x3f, /* KEY_F5 */ 0x40, /* KEY_F6 */ + 0x41, /* KEY_F7 */ 0x42, /* KEY_F8 */ + 0x43, /* KEY_F9 */ 0x44, /* KEY_F10 */ + 0x45, /* KEY_NumLock */ 0x46, /* KEY_ScrollLock */ + 0x47, /* KEY_KP_7 */ 0x48, /* KEY_KP_8 */ + 0x49, /* KEY_KP_9 */ 0x4a, /* KEY_KP_Minus */ + 0x4b, /* KEY_KP_4 */ 0x4c, /* KEY_KP_5 */ + 0x4d, /* KEY_KP_6 */ 0x4e, /* KEY_KP_Plus */ + 0x4f, /* KEY_KP_1 */ 0x50, /* KEY_KP_2 */ + 0x51, /* KEY_KP_3 */ 0x52, /* KEY_KP_0 */ + 0x53, /* KEY_KP_Decimal */ 0x54, /* KEY_SysReqest */ + 0x00, /* 0x55 */ 0x56, /* KEY_Less */ + 0x57, /* KEY_F11 */ 0x58, /* KEY_F12 */ + 0x66, /* KEY_Home */ 0x67, /* KEY_Up */ + 0x68, /* KEY_PgUp */ 0x69, /* KEY_Left */ + 0x5d, /* KEY_Begin */ 0x6a, /* KEY_Right */ + 0x6b, /* KEY_End */ 0x6c, /* KEY_Down */ + 0x6d, /* KEY_PgDown */ 0x6e, /* KEY_Insert */ + 0x6f, /* KEY_Delete */ 0x60, /* KEY_KP_Enter */ + 0x61, /* KEY_RCtrl */ 0x77, /* KEY_Pause */ + 0x63, /* KEY_Print */ 0x62, /* KEY_KP_Divide */ + 0x64, /* KEY_AltLang */ 0x65, /* KEY_Break */ + 0x00, /* KEY_LMeta */ 0x00, /* KEY_RMeta */ + 0x7A, /* KEY_Menu/FOCUS_PF11*/0x00, /* 0x6e */ + 0x7B, /* FOCUS_PF12 */ 0x00, /* 0x70 */ + 0x00, /* 0x71 */ 0x00, /* 0x72 */ + 0x59, /* FOCUS_PF2 */ 0x78, /* FOCUS_PF9 */ + 0x00, /* 0x75 */ 0x00, /* 0x76 */ + 0x5A, /* FOCUS_PF3 */ 0x5B, /* FOCUS_PF4 */ + 0x5C, /* FOCUS_PF5 */ 0x5D, /* FOCUS_PF6 */ + 0x5E, /* FOCUS_PF7 */ 0x5F, /* FOCUS_PF8 */ + 0x7C, /* JAP_86 */ 0x79, /* FOCUS_PF10 */ + 0x00, /* 0x7f */ +}; +#define NUM_AT2LNX (sizeof(at2lnx) / sizeof(at2lnx[0])) + +#define NUM_CUSTOMKEYS NR_KEYS + +static void +readKernelMapping(InputInfoPtr pInfo, KeySymsPtr pKeySyms, CARD8 *pModMap) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + KeySym *k; + int i; + int maxkey; + static unsigned char tbl[GLYPHS_PER_KEY] = + { + 0, /* unshifted */ + 1, /* shifted */ + 0, /* modeswitch unshifted */ + 0 /* modeswitch shifted */ + }; + + /* + * Read the mapping from the kernel. + * Since we're still using the XFree86 scancode->AT keycode mapping + * routines, we need to convert the AT keycodes to Linux keycodes, + * then translate the Linux keysyms into X keysyms. + * + * First, figure out which tables to use for the modeswitch columns + * above, from the XF86Config fields. + */ + tbl[2] = 8; /* alt */ + tbl[3] = tbl[2] | 1; + + if (pKbd->CustomKeycodes) { + k = map; + maxkey = NUM_CUSTOMKEYS; + } + else { + k = map+GLYPHS_PER_KEY; + maxkey = NUM_AT2LNX; + } + + for (i = 0; i < maxkey; ++i) + { + struct kbentry kbe; + int j; + + if (pKbd->CustomKeycodes) + kbe.kb_index = i; + else + kbe.kb_index = at2lnx[i]; + + for (j = 0; j < GLYPHS_PER_KEY; ++j, ++k) + { + unsigned short kval; + + *k = NoSymbol; + + kbe.kb_table = tbl[j]; + if ( + (!pKbd->CustomKeycodes && kbe.kb_index == 0) || + ioctl(pInfo->fd, KDGKBENT, &kbe)) + continue; + + kval = KVAL(kbe.kb_value); + switch (KTYP(kbe.kb_value)) + { + case KT_LATIN: + case KT_LETTER: + *k = linux_to_x[kval]; + break; + + case KT_FN: + if (kval <= 19) + *k = XK_F1 + kval; + else switch (kbe.kb_value) + { + case K_FIND: + *k = XK_Home; /* or XK_Find */ + break; + case K_INSERT: + *k = XK_Insert; + break; + case K_REMOVE: + *k = XK_Delete; + break; + case K_SELECT: + *k = XK_End; /* or XK_Select */ + break; + case K_PGUP: + *k = XK_Prior; + break; + case K_PGDN: + *k = XK_Next; + break; + case K_HELP: + *k = XK_Help; + break; + case K_DO: + *k = XK_Execute; + break; + case K_PAUSE: + *k = XK_Pause; + break; + case K_MACRO: + *k = XK_Menu; + break; + default: + break; + } + break; + + case KT_SPEC: + switch (kbe.kb_value) + { + case K_ENTER: + *k = XK_Return; + break; + case K_BREAK: + *k = XK_Break; + break; + case K_CAPS: + *k = XK_Caps_Lock; + break; + case K_NUM: + *k = XK_Num_Lock; + break; + case K_HOLD: + *k = XK_Scroll_Lock; + break; + case K_COMPOSE: + *k = XK_Multi_key; + break; + default: + break; + } + break; + + case KT_PAD: + switch (kbe.kb_value) + { + case K_PPLUS: + *k = XK_KP_Add; + break; + case K_PMINUS: + *k = XK_KP_Subtract; + break; + case K_PSTAR: + *k = XK_KP_Multiply; + break; + case K_PSLASH: + *k = XK_KP_Divide; + break; + case K_PENTER: + *k = XK_KP_Enter; + break; + case K_PCOMMA: + *k = XK_KP_Separator; + break; + case K_PDOT: + *k = XK_KP_Decimal; + break; + case K_PPLUSMINUS: + *k = XK_KP_Subtract; + break; + default: + if (kval <= 9) + *k = XK_KP_0 + kval; + break; + } + break; + + /* + * KT_DEAD keys are for accelerated diacritical creation. + */ + case KT_DEAD: + switch (kbe.kb_value) + { + case K_DGRAVE: + *k = XK_dead_grave; + break; + case K_DACUTE: + *k = XK_dead_acute; + break; + case K_DCIRCM: + *k = XK_dead_circumflex; + break; + case K_DTILDE: + *k = XK_dead_tilde; + break; + case K_DDIERE: + *k = XK_dead_diaeresis; + break; + } + break; + + case KT_CUR: + switch (kbe.kb_value) + { + case K_DOWN: + *k = XK_Down; + break; + case K_LEFT: + *k = XK_Left; + break; + case K_RIGHT: + *k = XK_Right; + break; + case K_UP: + *k = XK_Up; + break; + } + break; + + case KT_SHIFT: + switch (kbe.kb_value) + { + case K_ALTGR: + *k = XK_Alt_R; + break; + case K_ALT: + *k = (kbe.kb_index == 0x64 ? + XK_Alt_R : XK_Alt_L); + break; + case K_CTRL: + *k = (kbe.kb_index == 0x61 ? + XK_Control_R : XK_Control_L); + break; + case K_CTRLL: + *k = XK_Control_L; + break; + case K_CTRLR: + *k = XK_Control_R; + break; + case K_SHIFT: + *k = (kbe.kb_index == 0x36 ? + XK_Shift_R : XK_Shift_L); + break; + case K_SHIFTL: + *k = XK_Shift_L; + break; + case K_SHIFTR: + *k = XK_Shift_R; + break; + default: + break; + } + break; + + /* + * KT_ASCII keys accumulate a 3 digit decimal number that gets + * emitted when the shift state changes. We can't emulate that. + */ + case KT_ASCII: + break; + + case KT_LOCK: + if (kbe.kb_value == K_SHIFTLOCK) + *k = XK_Shift_Lock; + break; + + default: + break; + } + } + + if (k[-1] == k[-2]) k[-1] = NoSymbol; + if (k[-2] == k[-3]) k[-2] = NoSymbol; + if (k[-3] == k[-4]) k[-3] = NoSymbol; + if (k[-4] == k[-2] && k[-3] == k[-1]) k[-2] = k[-1] = NoSymbol; + if (k[-1] == k[-4] && k[-2] == k[-3] && k[-2] == NoSymbol) k[-1] =NoSymbol; + } + + if (!pKbd->CustomKeycodes) + return; + + /* + * Find the Mapping for the special server functions + */ + pKbd->specialMap = (TransMapPtr) xcalloc(NUM_CUSTOMKEYS, 1); + if (pKbd->specialMap != NULL) { + pKbd->specialMap->end = NUM_CUSTOMKEYS; + pKbd->specialMap->map = (unsigned char*) xcalloc(NUM_CUSTOMKEYS, 1); + if (pKbd->specialMap == NULL) { + xfree(pKbd->specialMap); + pKbd->specialMap = NULL; + } + } + if (pKbd->specialMap == NULL) { + xf86Msg(X_ERROR, "%s can't allocate \"special map\"\n", pInfo->name); + return; + } + + for (i = 0; i < NUM_CUSTOMKEYS; ++i) { + struct kbentry kbe; + int special = 0; + + kbe.kb_index = i; + kbe.kb_table = 0; /* Plain map */ + if (!ioctl(pInfo->fd, KDGKBENT, &kbe)) + switch (kbe.kb_value) { + case K(KT_LATIN,0x7f): /* This catches DEL too... But who cares? */ + special = KEY_BackSpace; + break; + case K_PMINUS: + special = KEY_KP_Minus; + break; + case K_PPLUS: + special = KEY_KP_Plus; + break; + case K_F1: + special = KEY_F1; + break; + case K_F2: + special = KEY_F2; + break; + case K_F3: + special = KEY_F3; + break; + case K_F4: + special = KEY_F4; + break; + case K_F5: + special = KEY_F5; + break; + case K_F6: + special = KEY_F6; + break; + case K_F7: + special = KEY_F7; + break; + case K_F8: + special = KEY_F8; + break; + case K_F9: + special = KEY_F9; + break; + case K_F10: + special = KEY_F10; + break; + case K_F11: + special = KEY_F11; + break; + case K_F12: + special = KEY_F12; + break; + case K_ALT: + special = KEY_Alt; + break; + case K_ALTGR: + special = KEY_AltLang; + break; + case K_CONS: + special = KEY_SysReqest; + break; + } + pKbd->specialMap->map[i] = special; + } +} diff --git a/hw/xfree86/os-support/linux/lnx_agp.c b/hw/xfree86/os-support/linux/lnx_agp.c new file mode 100644 index 000000000..13e423433 --- /dev/null +++ b/hw/xfree86/os-support/linux/lnx_agp.c @@ -0,0 +1,342 @@ +/* + * Abstraction of the AGP GART interface. + * + * This version is for both Linux and FreeBSD. + * + * Copyright © 2000 VA Linux Systems, Inc. + * Copyright © 2001 The XFree86 Project, Inc. + */ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_agp.c,v 3.10 2002/12/12 18:29:11 eich Exp $ */ + +#include "X.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "xf86OSpriv.h" + +#if defined(linux) +#include <asm/ioctl.h> +#include <linux/agpgart.h> +#elif defined(__FreeBSD__) || defined(__NetBSD__) +#include <sys/ioctl.h> +#include <sys/agpio.h> +#endif + +#ifndef AGP_DEVICE +#define AGP_DEVICE "/dev/agpgart" +#endif +/* AGP page size is independent of the host page size. */ +#ifndef AGP_PAGE_SIZE +#define AGP_PAGE_SIZE 4096 +#endif +#define AGPGART_MAJOR_VERSION 0 +#define AGPGART_MINOR_VERSION 99 + +static int gartFd = -1; +static int acquiredScreen = -1; +static Bool initDone = FALSE; +/* + * Close /dev/agpgart. This frees all associated memory allocated during + * this server generation. + */ +Bool +xf86GARTCloseScreen(int screenNum) +{ + if(gartFd != -1) { + close(gartFd); + acquiredScreen = -1; + gartFd = -1; + initDone = FALSE; + } + return TRUE; +} + +/* + * Open /dev/agpgart. Keep it open until xf86GARTCloseScreen is called. + */ +static Bool +GARTInit(int screenNum) +{ + struct _agp_info agpinf; + + if (initDone) + return (gartFd != -1); + + initDone = TRUE; + + if (gartFd == -1) + gartFd = open(AGP_DEVICE, O_RDWR, 0); + else + return FALSE; + + if (gartFd == -1) { + xf86DrvMsg(screenNum, X_ERROR, + "GARTInit: Unable to open " AGP_DEVICE " (%s)\n", + strerror(errno)); + return FALSE; + } + + xf86AcquireGART(-1); + /* Check the kernel driver version. */ + if (ioctl(gartFd, AGPIOC_INFO, &agpinf) != 0) { + xf86DrvMsg(screenNum, X_ERROR, + "GARTInit: AGPIOC_INFO failed (%s)\n", strerror(errno)); + close(gartFd); + gartFd = -1; + return FALSE; + } + xf86ReleaseGART(-1); + +#if defined(linux) + /* Per Dave Jones, every effort will be made to keep the + * agpgart interface backwards compatible, so allow all + * future versions. + */ + if ( +#if (AGPGART_MAJOR_VERSION > 0) /* quiet compiler */ + agpinf.version.major < AGPGART_MAJOR_VERSION || +#endif + (agpinf.version.major == AGPGART_MAJOR_VERSION && + agpinf.version.minor < AGPGART_MINOR_VERSION)) { + xf86DrvMsg(screenNum, X_ERROR, + "GARTInit: Kernel agpgart driver version is not current" + " (%d.%d vs %d.%d)\n", + agpinf.version.major, agpinf.version.minor, + AGPGART_MAJOR_VERSION, AGPGART_MINOR_VERSION); + close(gartFd); + gartFd = -1; + return FALSE; + } +#endif + + return TRUE; +} + +Bool +xf86AgpGARTSupported() +{ + return GARTInit(-1); +} + +AgpInfoPtr +xf86GetAGPInfo(int screenNum) +{ + struct _agp_info agpinf; + AgpInfoPtr info; + + if (!GARTInit(screenNum)) + return NULL; + + + if ((info = xcalloc(sizeof(AgpInfo), 1)) == NULL) { + xf86DrvMsg(screenNum, X_ERROR, + "xf86GetAGPInfo: Failed to allocate AgpInfo\n"); + return NULL; + } + + if (ioctl(gartFd, AGPIOC_INFO, &agpinf) != 0) { + xf86DrvMsg(screenNum, X_ERROR, + "xf86GetAGPInfo: AGPIOC_INFO failed (%s)\n", + strerror(errno)); + return NULL; + } + + info->bridgeId = agpinf.bridge_id; + info->agpMode = agpinf.agp_mode; + info->base = agpinf.aper_base; + info->size = agpinf.aper_size; + info->totalPages = agpinf.pg_total; + info->systemPages = agpinf.pg_system; + info->usedPages = agpinf.pg_used; + + return info; +} + +/* + * XXX If multiple screens can acquire the GART, should we have a reference + * count instead of using acquiredScreen? + */ + +Bool +xf86AcquireGART(int screenNum) +{ + if (screenNum != -1 && !GARTInit(screenNum)) + return FALSE; + + if (screenNum == -1 || acquiredScreen != screenNum) { + if (ioctl(gartFd, AGPIOC_ACQUIRE, 0) != 0) { + xf86DrvMsg(screenNum, X_WARNING, + "xf86AcquireGART: AGPIOC_ACQUIRE failed (%s)\n", + strerror(errno)); + return FALSE; + } + acquiredScreen = screenNum; + } + return TRUE; +} + +Bool +xf86ReleaseGART(int screenNum) +{ + if (screenNum != -1 && !GARTInit(screenNum)) + return FALSE; + + if (acquiredScreen == screenNum) { + /* + * The FreeBSD agp driver removes allocations on release. + * The Linux driver doesn't. xf86ReleaseGART() is expected + * to give up access to the GART, but not to remove any + * allocations. + */ +#if !defined(linux) + if (screenNum == -1) +#endif + { + if (ioctl(gartFd, AGPIOC_RELEASE, 0) != 0) { + xf86DrvMsg(screenNum, X_WARNING, + "xf86ReleaseGART: AGPIOC_RELEASE failed (%s)\n", + strerror(errno)); + return FALSE; + } + acquiredScreen = -1; + } + return TRUE; + } + return FALSE; +} + +int +xf86AllocateGARTMemory(int screenNum, unsigned long size, int type, + unsigned long *physical) +{ + struct _agp_allocate alloc; + int pages; + + /* + * Allocates "size" bytes of GART memory (rounds up to the next + * page multiple) or type "type". A handle (key) for the allocated + * memory is returned. On error, the return value is -1. + */ + + if (!GARTInit(screenNum) || acquiredScreen != screenNum) + return -1; + + pages = (size / AGP_PAGE_SIZE); + if (size % AGP_PAGE_SIZE != 0) + pages++; + + /* XXX check for pages == 0? */ + + alloc.pg_count = pages; + alloc.type = type; + + if (ioctl(gartFd, AGPIOC_ALLOCATE, &alloc) != 0) { + xf86DrvMsg(screenNum, X_WARNING, "xf86AllocateGARTMemory: " + "allocation of %d pages failed\n\t(%s)\n", pages, + strerror(errno)); + return -1; + } + + if (physical) + *physical = alloc.physical; + + return alloc.key; +} + + +/* Bind GART memory with "key" at "offset" */ +Bool +xf86BindGARTMemory(int screenNum, int key, unsigned long offset) +{ + struct _agp_bind bind; + int pageOffset; + + if (!GARTInit(screenNum) || acquiredScreen != screenNum) + return FALSE; + + if (acquiredScreen != screenNum) { + xf86DrvMsg(screenNum, X_ERROR, + "xf86BindGARTMemory: AGP not acquired by this screen\n"); + return FALSE; + } + + if (offset % AGP_PAGE_SIZE != 0) { + xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: " + "offset (0x%x) is not page-aligned (%d)\n", + offset, AGP_PAGE_SIZE); + return FALSE; + } + pageOffset = offset / AGP_PAGE_SIZE; + + xf86DrvMsgVerb(screenNum, X_INFO, 3, + "xf86BindGARTMemory: bind key %d at 0x%08x " + "(pgoffset %d)\n", key, offset, pageOffset); + + bind.pg_start = pageOffset; + bind.key = key; + + if (ioctl(gartFd, AGPIOC_BIND, &bind) != 0) { + xf86DrvMsg(screenNum, X_WARNING, "xf86BindGARTMemory: " + "binding of gart memory with key %d\n" + "\tat offset 0x%x failed (%s)\n", + key, offset, strerror(errno)); + return FALSE; + } + + return TRUE; +} + + +/* Unbind GART memory with "key" */ +Bool +xf86UnbindGARTMemory(int screenNum, int key) +{ + struct _agp_unbind unbind; + + if (!GARTInit(screenNum) || acquiredScreen != screenNum) + return FALSE; + + if (acquiredScreen != screenNum) { + xf86DrvMsg(screenNum, X_ERROR, + "xf86UnbindGARTMemory: AGP not acquired by this screen\n"); + return FALSE; + } + + unbind.priority = 0; + unbind.key = key; + + if (ioctl(gartFd, AGPIOC_UNBIND, &unbind) != 0) { + xf86DrvMsg(screenNum, X_WARNING, "xf86UnbindGARTMemory: " + "unbinding of gart memory with key %d " + "failed (%s)\n", key, strerror(errno)); + return FALSE; + } + + xf86DrvMsgVerb(screenNum, X_INFO, 3, + "xf86UnbindGARTMemory: unbind key %d\n", key); + + return TRUE; +} + + +/* XXX Interface may change. */ +Bool +xf86EnableAGP(int screenNum, CARD32 mode) +{ + agp_setup setup; + + if (!GARTInit(screenNum) || acquiredScreen != screenNum) + return FALSE; + + setup.agp_mode = mode; + if (ioctl(gartFd, AGPIOC_SETUP, &setup) != 0) { + xf86DrvMsg(screenNum, X_WARNING, "xf86EnableAGP: " + "AGPIOC_SETUP with mode %d failed (%s)\n", + mode, strerror(errno)); + return FALSE; + } + + return TRUE; +} + diff --git a/hw/xfree86/os-support/linux/lnx_apm.c b/hw/xfree86/os-support/linux/lnx_apm.c new file mode 100644 index 000000000..f2f326959 --- /dev/null +++ b/hw/xfree86/os-support/linux/lnx_apm.c @@ -0,0 +1,166 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_apm.c,v 3.13 2002/10/16 01:24:28 dawes Exp $ */ + +#include "X.h" +#include "os.h" +#include "xf86.h" +#include "xf86Priv.h" +#define XF86_OS_PRIVS +#include "xf86_OSproc.h" +#include "lnx.h" +#include <linux/apm_bios.h> +#include <unistd.h> +#include <sys/ioctl.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <errno.h> + +#define APM_PROC "/proc/apm" +#define APM_DEVICE "/dev/apm_bios" + +#ifndef APM_STANDBY_FAILED +# define APM_STANDBY_FAILED 0xf000 +#endif +#ifndef APM_SUSPEND_FAILED +# define APM_SUSPEND_FAILED 0xf001 +#endif + +static void lnxCloseAPM(void); +static pointer APMihPtr = NULL; + +static struct { + apm_event_t apmLinux; + pmEvent xf86; +} LinuxToXF86[] = { + { APM_SYS_STANDBY, XF86_APM_SYS_STANDBY }, + { APM_SYS_SUSPEND, XF86_APM_SYS_SUSPEND }, + { APM_NORMAL_RESUME, XF86_APM_NORMAL_RESUME }, + { APM_CRITICAL_RESUME, XF86_APM_CRITICAL_RESUME }, + { APM_LOW_BATTERY, XF86_APM_LOW_BATTERY }, + { APM_POWER_STATUS_CHANGE, XF86_APM_POWER_STATUS_CHANGE }, + { APM_UPDATE_TIME, XF86_APM_UPDATE_TIME }, + { APM_CRITICAL_SUSPEND, XF86_APM_CRITICAL_SUSPEND }, + { APM_USER_STANDBY, XF86_APM_USER_STANDBY }, + { APM_USER_SUSPEND, XF86_APM_USER_SUSPEND }, + { APM_STANDBY_RESUME, XF86_APM_STANDBY_RESUME }, +#if defined(APM_CAPABILITY_CHANGED) + { APM_CAPABILITY_CHANGED, XF86_CAPABILITY_CHANGED }, +#endif +#if 0 + { APM_STANDBY_FAILED, XF86_APM_STANDBY_FAILED }, + { APM_SUSPEND_FAILED, XF86_APM_SUSPEND_FAILED } +#endif +}; + +#define numApmEvents (sizeof(LinuxToXF86) / sizeof(LinuxToXF86[0])) + +/* + * APM is still under construction. + * I'm not sure if the places where I initialize/deinitialize + * apm is correct. Also I don't know what to do in SETUP state. + * This depends if wakeup gets called in this situation, too. + * Also we need to check if the action that is taken on an + * event is reasonable. + */ +static int +lnxPMGetEventFromOs(int fd, pmEvent *events, int num) +{ + int i,j,n; + apm_event_t linuxEvents[8]; + + if ((n = read( fd, linuxEvents, num * sizeof(apm_event_t) )) == -1) + return 0; + n /= sizeof(apm_event_t); + if (n > num) + n = num; + for (i = 0; i < n; i++) { + for (j = 0; j < numApmEvents; j++) + if (LinuxToXF86[j].apmLinux == linuxEvents[i]) { + events[i] = LinuxToXF86[j].xf86; + break; + } + if (j == numApmEvents) + events[i] = XF86_APM_UNKNOWN; + } + return n; +} + +static pmWait +lnxPMConfirmEventToOs(int fd, pmEvent event) +{ + switch (event) { + case XF86_APM_SYS_STANDBY: + case XF86_APM_USER_STANDBY: + if (ioctl( fd, APM_IOC_STANDBY, NULL )) + return PM_FAILED; + return PM_CONTINUE; + case XF86_APM_SYS_SUSPEND: + case XF86_APM_CRITICAL_SUSPEND: + case XF86_APM_USER_SUSPEND: + if (ioctl( fd, APM_IOC_SUSPEND, NULL )) { + if (errno == EBUSY) + return PM_CONTINUE; + else + return PM_FAILED; + } + return PM_CONTINUE; + case XF86_APM_STANDBY_RESUME: + case XF86_APM_NORMAL_RESUME: + case XF86_APM_CRITICAL_RESUME: + case XF86_APM_STANDBY_FAILED: + case XF86_APM_SUSPEND_FAILED: + return PM_CONTINUE; + default: + return PM_NONE; + } +} + +PMClose +xf86OSPMOpen(void) +{ + int fd, pfd; + +#ifdef DEBUG + ErrorF("APM: OSPMOpen called\n"); +#endif + if (APMihPtr || !xf86Info.pmFlag) + return NULL; + +#ifdef DEBUG + ErrorF("APM: Opening device\n"); +#endif + if ((fd = open( APM_DEVICE, O_RDWR )) > -1) { + if (access( APM_PROC, R_OK ) || + ((pfd = open( APM_PROC, O_RDONLY)) == -1)) { + xf86MsgVerb(X_WARNING,3,"Cannot open APM (%s) (%s)\n", + APM_PROC, strerror(errno)); + close(fd); + return NULL; + } else + close(pfd); + xf86PMGetEventFromOs = lnxPMGetEventFromOs; + xf86PMConfirmEventToOs = lnxPMConfirmEventToOs; + APMihPtr = xf86AddInputHandler(fd,xf86HandlePMEvents,NULL); + xf86MsgVerb(X_INFO,3,"Open APM successful\n"); + return lnxCloseAPM; + } + xf86MsgVerb(X_WARNING,3,"Open APM failed (%s) (%s)\n", APM_DEVICE, + strerror(errno)); + return NULL; +} + +static void +lnxCloseAPM(void) +{ + int fd; + +#ifdef DEBUG + ErrorF("APM: Closing device\n"); +#endif + if (APMihPtr) { + fd = xf86RemoveInputHandler(APMihPtr); + close(fd); + APMihPtr = NULL; + } +} + diff --git a/hw/xfree86/os-support/linux/lnx_axp.c b/hw/xfree86/os-support/linux/lnx_axp.c new file mode 100644 index 000000000..5813ef4e9 --- /dev/null +++ b/hw/xfree86/os-support/linux/lnx_axp.c @@ -0,0 +1,196 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_axp.c,v 1.5 2002/11/25 14:05:04 eich Exp $ */ + +#include <stdio.h> +#include "X.h" +#include "os.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86Axp.h" + +axpDevice lnxGetAXP(void); + +typedef struct + { char* sysName; + char* sysVari; + char* cpu; + axpDevice sys; } +AXP; + +static AXP axpList[] = { + { "Tsunami", NULL, NULL, TSUNAMI }, + { "Eiger", NULL, NULL, TSUNAMI }, + {"Noname", NULL, NULL, LCA }, + { "AlphaBook1", NULL, NULL, LCA }, + {"EB66", NULL, NULL, LCA}, + {"EB64+",NULL,NULL, APECS}, + {"Noritake",NULL,"EV5",CIA}, + {"Noritake",NULL,"EV56",CIA}, + {"Noritake",NULL,NULL,APECS}, + {"XL",NULL,NULL,APECS}, + {"Avanti",NULL,NULL,APECS}, + {"Mikasa",NULL,"EV5",CIA}, + {"Mikasa",NULL,"EV56",CIA}, + {"Mikasa",NULL,NULL,APECS}, + {"EB164","EB164",NULL,CIA}, + {"EB164","PC164", NULL,CIA}, + {"EB164","LX164",NULL, PYXIS}, + {"EB164","SX164",NULL, PYXIS}, + {"EB164","RX164",NULL, POLARIS}, + {"Alcor",NULL,NULL,CIA}, + {"Takara",NULL,NULL,CIA}, + {"Sable",NULL, "EV5",T2_GAMMA}, + {"Sable",NULL,"EV56",T2_GAMMA}, + {"Sable",NULL,NULL,T2}, + {"Rawhide",NULL,NULL,MCPCIA}, + {"Jensen",NULL,NULL,JENSEN}, + {"Miata",NULL,NULL,PYXIS_CIA}, + {"Ruffian",NULL,NULL,PYXIS_CIA}, + {"Nautilus",NULL,NULL,IRONGATE}, + {NULL,NULL,NULL,NONE} +}; + + +axpDevice +lnxGetAXP(void) +{ + FILE *file; + int count = 0; + char res[256]; + char cpu[255]; + char systype[255]; + char sysvari[255]; + if (!(file = fopen("/proc/cpuinfo","r"))) + return SYS_NONE; + do { + if (!fgets(res,0xff,file)) return SYS_NONE; + switch (count) { + case 1: + sscanf(res, "cpu model : %s",cpu); +#ifdef DEBUG + ErrorF("CPU %s\n",cpu); +#endif + break; + case 5: + sscanf(res, "system type : %s",systype); +#ifdef DEBUG + ErrorF("system type : %s\n",systype); +#endif + break; + case 6: + sscanf(res, "system variation : %s",sysvari); +#ifdef DEBUG + ErrorF("system variation: %s\n",sysvari); +#endif + break; + } + count++; + } while (count < 8); + + fclose(file); + + count = 0; + + do { + if (!axpList[count].sysName || !strcmp(axpList[count].sysName,systype)) { + if (axpList[count].sysVari && strcmp(axpList[count].sysVari,sysvari)) { + count++; + continue; + }; + if (axpList[count].cpu && strcmp(axpList[count].cpu,cpu)) { + count++; + continue; + } + return axpList[count].sys; + } + count++; + } while (1); +} + +/* + * pciconfig_iobase wrappers and dynamic i/o selection + */ +#include <linux/unistd.h> +#include <asm/pci.h> +#include <errno.h> + +/* glibc versions (single hose only) */ +extern void _outb(char val, unsigned long port); +extern void _outw(short val, unsigned long port); +extern void _outl(int val, unsigned long port); +extern unsigned int _inb(unsigned long port); +extern unsigned int _inw(unsigned long port); +extern unsigned int _inl(unsigned long port); + +extern void _dense_outb(char, unsigned long); +extern void _dense_outw(short, unsigned long); +extern void _dense_outl(int, unsigned long); +extern unsigned int _dense_inb(unsigned long); +extern unsigned int _dense_inw(unsigned long); +extern unsigned int _dense_inl(unsigned long); + +void (*_alpha_outb)(char, unsigned long) = _outb; +void (*_alpha_outw)(short, unsigned long) = _outw; +void (*_alpha_outl)(int, unsigned long) = _outl; +unsigned int (*_alpha_inb)(unsigned long) = _inb; +unsigned int (*_alpha_inw)(unsigned long) = _inw; +unsigned int (*_alpha_inl)(unsigned long) = _inl; + +static long _alpha_iobase_query(unsigned, int, int, int); +long (*_iobase)(unsigned, int, int, int) = _alpha_iobase_query; + +static long +_alpha_iobase(unsigned flags, int hose, int bus, int devfn) +{ +#ifdef __NR_pciconfig_iobase + if (bus < 0) { + bus = hose; + flags |= IOBASE_FROM_HOSE; + } + + return syscall(__NR_pciconfig_iobase, flags, bus, devfn); +#else + return -ENOSYS +#endif +} + +static long +_alpha_iobase_legacy(unsigned flags, int hose, int bus, int devfn) +{ + if (hose > 0) return -ENODEV; + if (flags & IOBASE_DENSE_MEM) return _bus_base(); + if (flags & IOBASE_SPARSE_MEM) return _bus_base_sparse(); + return 0; +} + +static long +_alpha_iobase_query(unsigned flags, int hose, int bus, int devfn) +{ + /* + * Only use iobase if the syscall is supported *and* it's + * a dense io system + */ + if (_alpha_iobase(IOBASE_DENSE_IO, 0, 0, 0) > 0) { + /* + * The syscall worked and it's a dense io system - take over the + * io subsystem + */ + _iobase = _alpha_iobase; + +#ifndef INCLUDE_XF86_NO_DOMAIN + /* + * Only take over the inx/outx functions if this is a dense I/O + * system *and* addressing domains are being used. The dense I/O + * routines expect I/O to be mapped (as done in xf86MapDomainIO) + */ + _alpha_outb = _dense_outb; + _alpha_outw = _dense_outw; + _alpha_outl = _dense_outl; + _alpha_inb = _dense_inb; + _alpha_inw = _dense_inw; + _alpha_inl = _dense_inl; +#endif /* !INCLUDE_XF86_NO_DOMAIN */ + } else _iobase = _alpha_iobase_legacy; + + return _iobase(flags, hose, bus, devfn); +} + diff --git a/hw/xfree86/os-support/linux/lnx_ev56.c b/hw/xfree86/os-support/linux/lnx_ev56.c new file mode 100644 index 000000000..bfcb0d70f --- /dev/null +++ b/hw/xfree86/os-support/linux/lnx_ev56.c @@ -0,0 +1,147 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_ev56.c,v 3.7 2002/11/25 14:05:04 eich Exp $ */ + +#include "X.h" +#include "input.h" +#include "scrnintstr.h" +#include "compiler.h" + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "xf86OSpriv.h" + +int readDense8(pointer Base, register unsigned long Offset); +int readDense16(pointer Base, register unsigned long Offset); +int readDense32(pointer Base, register unsigned long Offset); +void +writeDenseNB8(int Value, pointer Base, register unsigned long Offset); +void +writeDenseNB16(int Value, pointer Base, register unsigned long Offset); +void +writeDenseNB32(int Value, pointer Base, register unsigned long Offset); +void +writeDense8(int Value, pointer Base, register unsigned long Offset); +void +writeDense16(int Value, pointer Base, register unsigned long Offset); +void +writeDense32(int Value, pointer Base, register unsigned long Offset); + +int +readDense8(pointer Base, register unsigned long Offset) +{ + mem_barrier(); + return *(volatile CARD8*) ((unsigned long)Base+(Offset)); +} + +int +readDense16(pointer Base, register unsigned long Offset) +{ + mem_barrier(); + return *(volatile CARD16*) ((unsigned long)Base+(Offset)); +} + +int +readDense32(pointer Base, register unsigned long Offset) +{ + mem_barrier(); + return *(volatile CARD32*)((unsigned long)Base+(Offset)); +} + +void +writeDenseNB8(int Value, pointer Base, register unsigned long Offset) +{ + *(volatile CARD8*)((unsigned long)Base+(Offset)) = Value; +} + +void +writeDenseNB16(int Value, pointer Base, register unsigned long Offset) +{ + *(volatile CARD16*)((unsigned long)Base + (Offset)) = Value; +} + +void +writeDenseNB32(int Value, pointer Base, register unsigned long Offset) +{ + *(volatile CARD32*)((unsigned long)Base+(Offset)) = Value; +} + +void +writeDense8(int Value, pointer Base, register unsigned long Offset) +{ + write_mem_barrier(); + *(volatile CARD8 *)((unsigned long)Base+(Offset)) = Value; +} + +void +writeDense16(int Value, pointer Base, register unsigned long Offset) +{ + write_mem_barrier(); + *(volatile CARD16 *)((unsigned long)Base+(Offset)) = Value; +} + +void +writeDense32(int Value, pointer Base, register unsigned long Offset) +{ + write_mem_barrier(); + *(volatile CARD32 *)((unsigned long)Base+(Offset)) = Value; +} + + +#ifndef INCLUDE_XF86_NO_DOMAIN + +void +_dense_outb(char val, unsigned long port) +{ + if ((port & ~0xffff) == 0) return _outb(val, port); + + write_mem_barrier(); + *(volatile CARD8 *)port = val; +} + +void +_dense_outw(short val, unsigned long port) +{ + if ((port & ~0xffff) == 0) return _outw(val, port); + + write_mem_barrier(); + *(volatile CARD16 *)port = val; +} + +void +_dense_outl(int val, unsigned long port) +{ + if ((port & ~0xffff) == 0) return _outl(val, port); + + write_mem_barrier(); + *(volatile CARD32 *)port = val; +} + +unsigned int +_dense_inb(unsigned long port) +{ + if ((port & ~0xffff) == 0) return _inb(port); + + mem_barrier(); + return *(volatile CARD8 *)port; +} + +unsigned int +_dense_inw(unsigned long port) +{ + if ((port & ~0xffff) == 0) return _inw(port); + + mem_barrier(); + return *(volatile CARD16 *)port; +} + +unsigned int +_dense_inl(unsigned long port) +{ + if ((port & ~0xffff) == 0) return _inl(port); + + mem_barrier(); + return *(volatile CARD32 *)port; +} + +#endif /* !INCLUDE_XF86_NO_DOMAIN */ + diff --git a/hw/xfree86/os-support/linux/lnx_kbd.c b/hw/xfree86/os-support/linux/lnx_kbd.c new file mode 100644 index 000000000..f2d508c04 --- /dev/null +++ b/hw/xfree86/os-support/linux/lnx_kbd.c @@ -0,0 +1,523 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_kbd.c,v 1.2 2003/02/17 15:11:57 dawes Exp $ */ + +/* + * Copyright (c) 2002 by The XFree86 Project, Inc. + * Author: Ivan Pascal. + * + * Based on the code from lnx_io.c which is + * Copyright 1992 by Orest Zborowski <obz@Kodak.com> + * Copyright 1993 by David Dawes <dawes@xfree86.org> + */ + +#define NEED_EVENTS +#include "X.h" + +#include "compiler.h" + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +#include "xf86Xinput.h" +#include "xf86OSKbd.h" +#include "atKeynames.h" +#include "lnx_kbd.h" + +#define KBC_TIMEOUT 250 /* Timeout in ms for sending to keyboard controller */ + +static KbdProtocolRec protocols[] = { + {"standard", PROT_STD }, + { NULL, PROT_UNKNOWN } +}; + +extern Bool VTSwitchEnabled; +#ifdef USE_VT_SYSREQ +extern Bool VTSysreqToggle; +#endif + +static void +SoundBell(InputInfoPtr pInfo, int loudness, int pitch, int duration) +{ + if (loudness && pitch) + { + ioctl(pInfo->fd, KDMKTONE, + ((1193190 / pitch) & 0xffff) | + (((unsigned long)duration * + loudness / 50) << 16)); + } +} + +static void +SetKbdLeds(InputInfoPtr pInfo, int leds) +{ + int real_leds = 0; + +#if defined (__sparc__) + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + if (pKbd->sunKbd) { + if (leds & 0x08) real_leds |= XLED1; + if (leds & 0x04) real_leds |= XLED3; + if (leds & 0x02) real_leds |= XLED4; + if (leds & 0x01) real_leds |= XLED2; + leds = real_leds; + real_leds = 0; + } +#endif /* defined (__sparc__) */ +#ifdef LED_CAP + if (leds & XLED1) real_leds |= LED_CAP; + if (leds & XLED2) real_leds |= LED_NUM; + if (leds & XLED3) real_leds |= LED_SCR; +#ifdef LED_COMP + if (leds & XLED4) real_leds |= LED_COMP; +#else + if (leds & XLED4) real_leds |= LED_SCR; +#endif +#endif + ioctl(pInfo->fd, KDSETLED, real_leds); +} + +static int +GetKbdLeds(InputInfoPtr pInfo) +{ + int real_leds, leds = 0; + + ioctl(pInfo->fd, KDGETLED, &real_leds); + + if (real_leds & LED_CAP) leds |= XLED1; + if (real_leds & LED_NUM) leds |= XLED2; + if (real_leds & LED_SCR) leds |= XLED3; + + return(leds); +} + +/* kbd rate stuff based on kbdrate.c from Rik Faith <faith@cs.unc.edu> et.al. + * from util-linux-2.9t package */ + + +#ifdef __sparc__ +#include <asm/param.h> +#include <asm/kbio.h> +#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 */ +} + +static void +SetKbdRepeat(InputInfoPtr pInfo, char rad) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + int i; + int timeout; + int value = 0x7f; /* Maximum delay with slowest rate */ + +#ifdef __sparc__ + int rate = 500; /* Default rate */ + int delay = 200; /* Default delay */ +#else + int rate = 300; /* Default rate */ + int delay = 250; /* Default delay */ +#endif + + 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 )) + + if (pKbd->rate >= 0) + rate = pKbd->rate * 10; + if (pKbd->delay >= 0) + delay = pKbd->delay; + + 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__ */ +} + +typedef struct { + int kbdtrans; + struct termios kbdtty; +} LnxKbdPrivRec, *LnxKbdPrivPtr; + +static int +KbdInit(InputInfoPtr pInfo, int what) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + LnxKbdPrivPtr priv = (LnxKbdPrivPtr) pKbd->private; + + if (pKbd->isConsole) { + ioctl (pInfo->fd, KDGKBMODE, &(priv->kbdtrans)); + tcgetattr (pInfo->fd, &(priv->kbdtty)); + } + if (!pKbd->CustomKeycodes) { + pKbd->RemapScanCode = ATScancode; + } + + return Success; +} + +static int +KbdOn(InputInfoPtr pInfo, int what) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + LnxKbdPrivPtr priv = (LnxKbdPrivPtr) pKbd->private; + struct termios nTty; + + if (pKbd->isConsole) { + if (pKbd->CustomKeycodes) + ioctl(pInfo->fd, KDSKBMODE, K_MEDIUMRAW); + else + ioctl(pInfo->fd, KDSKBMODE, K_RAW); + + nTty = priv->kbdtty; + nTty.c_iflag = (IGNPAR | IGNBRK) & (~PARMRK) & (~ISTRIP); + nTty.c_oflag = 0; + nTty.c_cflag = CREAD | CS8; + nTty.c_lflag = 0; + nTty.c_cc[VTIME]=0; + nTty.c_cc[VMIN]=1; + cfsetispeed(&nTty, 9600); + cfsetospeed(&nTty, 9600); + tcsetattr(pInfo->fd, TCSANOW, &nTty); + } + return Success; +} + +static int +KbdOff(InputInfoPtr pInfo, int what) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + LnxKbdPrivPtr priv = (LnxKbdPrivPtr) pKbd->private; + + if (pKbd->isConsole) { + ioctl(pInfo->fd, KDSKBMODE, priv->kbdtrans); + tcsetattr(pInfo->fd, TCSANOW, &(priv->kbdtty)); + } + return Success; +} + +static int +GetSpecialKey(InputInfoPtr pInfo, int scanCode) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + int specialkey = scanCode; + +#if defined (__sparc__) + if (pKbd->sunKbd) { + switch (scanCode) { + case 0x2b: specialkey = KEY_BackSpace; break; + case 0x47: specialkey = KEY_KP_Minus; break; + case 0x7d: specialkey = KEY_KP_Plus; break; + /* XXX needs cases for KEY_KP_Divide and KEY_KP_Multiply */ + case 0x05: specialkey = KEY_F1; break; + case 0x06: specialkey = KEY_F2; break; + case 0x08: specialkey = KEY_F3; break; + case 0x0a: specialkey = KEY_F4; break; + case 0x0c: specialkey = KEY_F5; break; + case 0x0e: specialkey = KEY_F6; break; + case 0x10: specialkey = KEY_F7; break; + case 0x11: specialkey = KEY_F8; break; + case 0x12: specialkey = KEY_F9; break; + case 0x07: specialkey = KEY_F10; break; + case 0x09: specialkey = KEY_F11; break; + case 0x0b: specialkey = KEY_F12; break; + default: specialkey = 0; break; + } + return specialkey; + } +#endif + + if (pKbd->CustomKeycodes) { + specialkey = pKbd->specialMap->map[scanCode]; + } + return specialkey; +} + +#define ModifierSet(k) ((modifiers & (k)) == (k)) + +static +Bool SpecialKey(InputInfoPtr pInfo, int key, Bool down, int modifiers) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + + if(!pKbd->vtSwitchSupported) + return FALSE; + + if ((ModifierSet(ControlMask | AltMask)) || + (ModifierSet(ControlMask | AltLangMask))) { + if (VTSwitchEnabled && !xf86Info.vtSysreq) { + switch (key) { + case KEY_F1: + case KEY_F2: + case KEY_F3: + case KEY_F4: + case KEY_F5: + case KEY_F6: + case KEY_F7: + case KEY_F8: + case KEY_F9: + case KEY_F10: + if (down) { + ioctl(xf86Info.consoleFd, VT_ACTIVATE, key - KEY_F1 + 1); + return TRUE; + } + case KEY_F11: + case KEY_F12: + if (down) { + ioctl(xf86Info.consoleFd, VT_ACTIVATE, key - KEY_F11 + 11); + return TRUE; + } + } + } + } +#ifdef USE_VT_SYSREQ + if (VTSwitchEnabled && xf86Info.vtSysreq) { + switch (key) { + case KEY_F1: + case KEY_F2: + case KEY_F3: + case KEY_F4: + case KEY_F5: + case KEY_F6: + case KEY_F7: + case KEY_F8: + case KEY_F9: + case KEY_F10: + if (VTSysreqToggle && down) { + ioctl(xf86Info.consoleFd, VT_ACTIVATE, key - KEY_F1 + 1); + VTSysreqToggle = FALSE; + return TRUE; + } + break; + case KEY_F11: + case KEY_F12: + if (VTSysreqToggle && down) { + ioctl(xf86Info.consoleFd, VT_ACTIVATE, key - KEY_F11 + 11); + VTSysreqToggle = FALSE; + return TRUE; + } + break; + /* Ignore these keys -- ie don't let them cancel an alt-sysreq */ + case KEY_Alt: + case KEY_AltLang: + break; + case KEY_SysReqest: + if ((ModifierSet(AltMask) || ModifierSet(AltLangMask)) && down) + VTSysreqToggle = TRUE; + break; + default: + /* + * We only land here when Alt-SysReq is followed by a + * non-switching key. + */ + if (VTSysreqToggle) + VTSysreqToggle = FALSE; + } + } +#endif /* USE_VT_SYSREQ */ + return FALSE; +} + +static void +stdReadInput(InputInfoPtr pInfo) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + unsigned char rBuf[64]; + int nBytes, i; + if ((nBytes = read( pInfo->fd, (char *)rBuf, sizeof(rBuf))) > 0) { + for (i = 0; i < nBytes; i++) + pKbd->PostEvent(pInfo, rBuf[i] & 0x7f, + rBuf[i] & 0x80 ? FALSE : TRUE); + } +} + +static Bool +OpenKeyboard(InputInfoPtr pInfo) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + int i; + KbdProtocolId prot = PROT_UNKNOWN; + char *s; + + s = xf86SetStrOption(pInfo->options, "Protocol", NULL); + for (i = 0; protocols[i].name; i++) { + if (xf86NameCmp(s, protocols[i].name) == 0) { + prot = protocols[i].id; + break; + } + } + + switch (prot) { + case PROT_STD: + pInfo->read_input = stdReadInput; + break; + default: + xf86Msg(X_ERROR,"\"%s\" is not a valid keyboard protocol name\n", s); + xfree(s); + return FALSE; + } + + xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, s); + xfree(s); + + s = xf86SetStrOption(pInfo->options, "Device", NULL); + if (s == NULL) { + pInfo->fd = xf86Info.consoleFd; + pKbd->isConsole = TRUE; + } else { + pInfo->fd = open(s, O_RDONLY | O_NONBLOCK | O_EXCL); + if (pInfo->fd == -1) { + xf86Msg(X_ERROR, "%s: cannot open \"%s\"\n", pInfo->name, s); + xfree(s); + return FALSE; + } + pKbd->isConsole = FALSE; + xfree(s); + } + + if (pKbd->isConsole) + pKbd->vtSwitchSupported = TRUE; + + return TRUE; +} + +Bool +xf86OSKbdPreInit(InputInfoPtr pInfo) +{ + KbdDevPtr pKbd = pInfo->private; + + pKbd->KbdInit = KbdInit; + pKbd->KbdOn = KbdOn; + pKbd->KbdOff = KbdOff; + pKbd->Bell = SoundBell; + pKbd->SetLeds = SetKbdLeds; + pKbd->GetLeds = GetKbdLeds; + pKbd->SetKbdRepeat = SetKbdRepeat; + pKbd->KbdGetMapping = KbdGetMapping; + pKbd->SpecialKey = SpecialKey; + + pKbd->RemapScanCode = NULL; + pKbd->GetSpecialKey = GetSpecialKey; + + pKbd->OpenKeyboard = OpenKeyboard; + pKbd->vtSwitchSupported = FALSE; + + pKbd->private = xcalloc(sizeof(LnxKbdPrivRec), 1); + if (pKbd->private == NULL) { + xf86Msg(X_ERROR,"can't allocate keyboard OS private data\n"); + return FALSE; + } + +#if defined(__powerpc__) + { + FILE *f; + f = fopen("/proc/sys/dev/mac_hid/keyboard_sends_linux_keycodes","r"); + if (f) { + if (fgetc(f) == '0') + pKbd->CustomKeycodes = TRUE; + fclose(f); + } + } +#endif + return TRUE; +} diff --git a/hw/xfree86/os-support/linux/lnx_kbd.h b/hw/xfree86/os-support/linux/lnx_kbd.h new file mode 100644 index 000000000..ac783bfbc --- /dev/null +++ b/hw/xfree86/os-support/linux/lnx_kbd.h @@ -0,0 +1,5 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_kbd.h,v 1.1 2002/10/11 01:40:35 dawes Exp $ */ + +extern void KbdGetMapping(InputInfoPtr pInfo, KeySymsPtr pKeySyms, + CARD8 *pModMap); + diff --git a/hw/xfree86/os-support/linux/lnx_kmod.c b/hw/xfree86/os-support/linux/lnx_kmod.c new file mode 100644 index 000000000..0cb69b209 --- /dev/null +++ b/hw/xfree86/os-support/linux/lnx_kmod.c @@ -0,0 +1,109 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_kmod.c,v 3.6 2001/10/31 22:50:30 tsi Exp $ */ + +#include <errno.h> +#include <fcntl.h> +#include <unistd.h> +#include <sys/wait.h> +#include <signal.h> +#include "xf86_OSlib.h" +#include "xf86.h" + + +#define MODPROBE_PATH_FILE "/proc/sys/kernel/modprobe" +#define MAX_PATH 1024 + + +#if 0 +/* XFree86 #defines execl to be the xf86execl() function which does + * a fork AND exec. We don't want that. We want the regular, + * standard execl(). + */ +#ifdef execl +#undef execl +#endif +#endif + + +/* + * Load a Linux kernel module. + * This is used by the DRI/DRM to load a DRM kernel module when + * the X server starts. It could be used for other purposes in the future. + * Input: + * modName - name of the kernel module (Ex: "tdfx") + * Return: + * 0 for failure, 1 for success + */ +int +xf86LoadKernelModule(const char *modName) +{ + char mpPath[MAX_PATH] = ""; + int fd = -1, status, n; + pid_t pid; + + /* get the path to the modprobe program */ + fd = open(MODPROBE_PATH_FILE, O_RDONLY); + if (fd >= 0) { + int count = read(fd, mpPath, MAX_PATH - 1); + if (count <= 0) { + mpPath[0] = 0; + } + else if (mpPath[count - 1] == '\n') { + mpPath[count - 1] = 0; /* replaces \n with \0 */ + } + close(fd); + /* if this worked, mpPath will be "/sbin/modprobe" or similar. */ + } + + if (mpPath[0] == 0) { + /* we failed to get the path from the system, use a default */ + strcpy(mpPath, "/sbin/modprobe"); + } + + /* now fork/exec the modprobe command */ + /* + * It would be good to capture stdout/stderr so that it can be directed + * to the log file. modprobe errors currently are missing from the log + * file. + */ + switch (pid = fork()) { + case 0: /* child */ + /* change real/effective user ID to 0/0 as we need to + * preinstall agpgart module for some DRM modules + */ + if (setreuid(0,0)) { + xf86Msg(X_WARNING,"LoadKernelModule: " + "Setting of real/effective user Id to 0/0 failed"); + } + setenv("PATH","/sbin",1); + n = execl(mpPath, "modprobe", modName, NULL); + xf86Msg(X_WARNING,"LoadKernelModule %s\n",strerror(errno)); + exit(EXIT_FAILURE); /* if we get here the child's exec failed */ + break; + case -1: /* fork failed */ + return 0; + default: /* fork worked */ + { + /* XXX we loop over waitpid() because it sometimes fails on + * the first attempt. Don't know why! + */ + int count = 0, p; + do { + p = waitpid(pid, &status, 0); + } while (p == -1 && count++ < 4); + + if (p == -1) { + return 0; + } + + if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { + return 1; /* success! */ + } + else { + return 0; + } + } + } + + /* never get here */ + return 0; +} diff --git a/hw/xfree86/os-support/linux/lnx_mouse.c b/hw/xfree86/os-support/linux/lnx_mouse.c new file mode 100644 index 000000000..8bc7e6331 --- /dev/null +++ b/hw/xfree86/os-support/linux/lnx_mouse.c @@ -0,0 +1,29 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_mouse.c,v 1.1 1999/05/17 13:17:18 dawes Exp $ */ + +/* + * Copyright 1999 by The XFree86 Project, Inc. + */ + +#include "X.h" +#include "xf86.h" +#include "xf86Xinput.h" +#include "xf86OSmouse.h" + +static int +SupportedInterfaces(void) +{ + return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_XPS2 | MSE_AUTO; +} + +OSMouseInfoPtr +xf86OSMouseInit(int flags) +{ + OSMouseInfoPtr p; + + p = xcalloc(sizeof(OSMouseInfoRec), 1); + if (!p) + return NULL; + p->SupportedInterfaces = SupportedInterfaces; + return p; +} + diff --git a/hw/xfree86/os-support/linux/lnx_pci.c b/hw/xfree86/os-support/linux/lnx_pci.c new file mode 100644 index 000000000..5477b9130 --- /dev/null +++ b/hw/xfree86/os-support/linux/lnx_pci.c @@ -0,0 +1,85 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/linux/lnx_pci.c,v 3.9 2003/02/17 15:29:22 dawes Exp $ */ + +#include <stdio.h> +#include "X.h" +#include "os.h" +#include "xf86.h" +#include "xf86Priv.h" +#define XF86_OS_PRIVS +#include "xf86_OSproc.h" +#include "xf86Pci.h" + +#ifdef __sparc__ +#define PCIADDR_TYPE long long +#define PCIADDR_IGNORE_FMT "%*x" +#define PCIADDR_FMT "%llx" +#else +#define PCIADDR_TYPE long +#define PCIADDR_IGNORE_FMT "%*x" +#define PCIADDR_FMT "%lx" +#endif + +Bool +xf86GetPciSizeFromOS(PCITAG tag, int index, int* bits) +{ + FILE *file; + char c[0x200]; + char *res; + unsigned int bus, devfn, dev, fn; + unsigned PCIADDR_TYPE size[7]; + unsigned int num; + signed PCIADDR_TYPE Size; + + if (index > 7) + return FALSE; + + if (!(file = fopen("/proc/bus/pci/devices","r"))) + return FALSE; + do { + res = fgets(c,0x1ff,file); + if (res) { + num = sscanf(res, + /*bus+dev vendorid deviceid irq */ + "%02x%02x\t%*04x%*04x\t%*x" + /* 7 PCI resource base addresses */ + "\t" PCIADDR_IGNORE_FMT + "\t" PCIADDR_IGNORE_FMT + "\t" PCIADDR_IGNORE_FMT + "\t" PCIADDR_IGNORE_FMT + "\t" PCIADDR_IGNORE_FMT + "\t" PCIADDR_IGNORE_FMT + "\t" PCIADDR_IGNORE_FMT + /* 7 PCI resource sizes, and then optionally a driver name */ + "\t" PCIADDR_FMT + "\t" PCIADDR_FMT + "\t" PCIADDR_FMT + "\t" PCIADDR_FMT + "\t" PCIADDR_FMT + "\t" PCIADDR_FMT + "\t" PCIADDR_FMT, + &bus,&devfn,&size[0],&size[1],&size[2],&size[3], + &size[4],&size[5],&size[6]); + if (num != 9) { /* apparantly not 2.3 style */ + fclose(file); + return FALSE; + } + dev = devfn >> 3; + fn = devfn & 0x7; + if (tag == pciTag(bus,dev,fn)) { + *bits = 0; + if (size[index] != 0) { + Size = size[index] - ((PCIADDR_TYPE) 1); + while (Size & ((PCIADDR_TYPE) 0x01)) { + Size = Size >> ((PCIADDR_TYPE) 1); + (*bits)++; + } + } + fclose(file); + return TRUE; + } + } + } while (res); + + fclose(file); + return FALSE; +} diff --git a/hw/xfree86/os-support/lynxos/lynx_mouse.c b/hw/xfree86/os-support/lynxos/lynx_mouse.c new file mode 100644 index 000000000..1dc5ff8af --- /dev/null +++ b/hw/xfree86/os-support/lynxos/lynx_mouse.c @@ -0,0 +1,30 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_mouse.c,v 1.1 1999/05/22 08:40:14 dawes Exp $ */ + +/* + * Copyright 1999 by The XFree86 Project, Inc. + */ + +#include "X.h" +#include "xf86.h" +#include "xf86Xinput.h" +#include "xf86OSmouse.h" + +static int +SupportedInterfaces(void) +{ + /* XXX Need to check this. */ + return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO; +} + +OSMouseInfoPtr +xf86OSMouseInit(int flags) +{ + OSMouseInfoPtr p; + + p = xcalloc(sizeof(OSMouseInfoRec), 1); + if (!p) + return NULL; + p->SupportedInterfaces = SupportedInterfaces; + return p; +} + diff --git a/hw/xfree86/os-support/lynxos/lynx_noinline.c b/hw/xfree86/os-support/lynxos/lynx_noinline.c new file mode 100644 index 000000000..858b0eb65 --- /dev/null +++ b/hw/xfree86/os-support/lynxos/lynx_noinline.c @@ -0,0 +1,174 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_noinline.c,v 3.6 2002/01/25 21:56:20 tsi Exp $ */ +/* + * 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. + */ + +#if /* NO_INLINE && */ defined(__powerpc__) + +#include "xf86Pci.h" + +extern volatile unsigned char *ioBase; + +void +eieio() +{ + __asm__ __volatile__ ("eieio"); +} + +unsigned long +ldl_brx(volatile unsigned char *base, int ndx) +{ + register unsigned long tmp = *(volatile unsigned long *)(base+ndx); + return( ((tmp & 0x000000ff) << 24) | + ((tmp & 0x0000ff00) << 8) | + ((tmp & 0x00ff0000) >> 8) | + ((tmp & 0xff000000) >> 24) ); +} + +unsigned short +ldw_brx(volatile unsigned char *base, int ndx) +{ + register unsigned short tmp = *(volatile unsigned short *)(base+ndx); + return((tmp << 8) | (tmp >> 8)); +} + +void +stl_brx(unsigned long val, volatile unsigned char *base, int ndx) +{ + unsigned char *p = (unsigned char *)&val; + unsigned long tmp = (p[3] << 24) | (p[2] << 16) | (p[1] << 8) | (p[0] << 0); + *(volatile unsigned long *)(base+ndx) = tmp; +} + +void +stw_brx(unsigned short val, volatile unsigned char *base, int ndx) +{ + unsigned char *p = (unsigned char *)&val; + unsigned short tmp = (p[1] << 8) | p[0]; + *(volatile unsigned short *)(base+ndx) = tmp; +} + +void +outb(IOADDRESS port, unsigned char value) +{ + *((volatile unsigned char *)(ioBase + port)) = value; eieio(); +} + +void +outw(IOADDRESS port, unsigned short value) +{ + stw_brx(value, ioBase, port); eieio(); +} + +void +outl(IOADDRESS port, unsigned int value) +{ + stl_brx(value, ioBase, port); eieio(); +} + +unsigned char +inb(IOADDRESS port) +{ + unsigned char val; + + val = *((volatile unsigned char *)(ioBase + port)); eieio(); + return(val); +} + +unsigned short +inw(IOADDRESS port) +{ + unsigned short val; + + val = ldw_brx(ioBase, port); eieio(); + return(val); +} + +unsigned int +inl(IOADDRESS port) +{ + unsigned int val; + + val = ldl_brx(ioBase, port); eieio(); + return(val); +} + +unsigned long +ldl_u(void *p) +{ + return (((*(unsigned char *)(p)) | + (*((unsigned char *)(p)+1)<<8) | + (*((unsigned char *)(p)+2)<<16) | + (*((unsigned char *)(p)+3)<<24))); +} + +unsigned long +ldq_u(void *p) +{ + return ldl_u(p); +} + +unsigned short +ldw_u(void *p) +{ + return(((*(unsigned char *)(p)) | + (*((unsigned char *)(p)+1)<<8))); +} + +void +stl_u(unsigned long v, void *p) +{ + + (*(unsigned char *)(p)) = (v); + (*((unsigned char *)(p)+1)) = ((v) >> 8); + (*((unsigned char *)(p)+2)) = ((v) >> 16); + (*((unsigned char *)(p)+3)) = ((v) >> 24); +} + +void +stq_u(unsigned long v, void *p) +{ + stl_u(v,p); +} + +void +stw_u(unsigned short v, void *p) +{ + (*(unsigned char *)(p)) = (v); + (*((unsigned char *)(p)+1)) = ((v) >> 8); +} + + +void +mem_barrier(void) +{ + __asm__ __volatile__("eieio"); +} + +void +write_mem_barrier(void) +{ + __asm__ __volatile__("eieio"); +} + +#endif /* NO_INLINE && __powerpc__ */ diff --git a/hw/xfree86/os-support/lynxos/lynx_ppc.c b/hw/xfree86/os-support/lynxos/lynx_ppc.c new file mode 100644 index 000000000..e587b7ee0 --- /dev/null +++ b/hw/xfree86/os-support/lynxos/lynx_ppc.c @@ -0,0 +1,52 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/lynxos/lynx_ppc.c,v 1.1 2002/12/14 04:41:14 dawes Exp $ */ +/* + * 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. + */ + +void ppc_flush_icache() +{ +__asm__ __volatile__ (" \ + mflr 0 ;\ + stw 31,-4(1) ;\ + stw 0,8(1) ;\ + stwu 1,-64(1) ;\ + mr 31,1 ;\ + stw 3,88(31) ;\ + li 6, 0 ;\ + dcbf 3, 6 ;\ + li 5, 32 ;\ + dcbf 3, 5 ;\ + sync ;\ + li 4,0 ;\ + icbi 3,4 ;\ + li 7,32 ;\ + icbi 3,7 ;\ + sync ;\ + isync ;\ + lwz 1,0(1) ;\ + lwz 0,8(1) ;\ + mtlr 0 ;\ + lwz 31,-4(1) ;\ + blr ;\ +"); +} diff --git a/hw/xfree86/os-support/misc/BUSmemcpy.S b/hw/xfree86/os-support/misc/BUSmemcpy.S new file mode 100644 index 000000000..e4ff36c62 --- /dev/null +++ b/hw/xfree86/os-support/misc/BUSmemcpy.S @@ -0,0 +1,156 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/misc/BUSmemcpy.S,v 1.1 1999/07/10 07:24:49 dawes Exp $ */ +/****************************************************************************** + Copyright 1993 by Glenn G. Lai + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +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 Glenn G. Lai not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +Glenn G. Lai DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL 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. + +Glenn G. Lai +P.O. Box 4314 +Austin, Tx 78765 +(glenn@cs.utexas.edu) +8/9/93 +******************************************************************************/ +/* $XConsortium: BUSmemcpy.s /main/4 1996/02/21 17:39:34 kaleb $ */ + +/* + * Modified to use long-alignment of video memory rather than word-alignment + * to improve performance for LocalBus video cards. Function names changed + * from ISAToMem and MemToISA to BusToMem and MemToBus. + * + * David Dawes <dawes@XFree86.org>, 25 August 1993. + */ + + +#include "assyntax.h" + + FILE("BUSmemcpy.s") + + AS_BEGIN + +/* BusToMem copies from video memory to main memory + MemToBus copies from main memory to video memory + + void xf86BusToMem(unsigned char *dst, unsigned char *src, int len); + void xf86MemToBus(unsigned char *dst, unsigned char *src, int len); +*/ + +#define dst REGOFF(4,ESP) +#define src REGOFF(8,ESP) +#define len REGOFF(12,ESP) + + GLOBL GLNAME(xf86BusToMem) + GLOBL GLNAME(xf86MemToBus) + + SEG_DATA +copyright: + STRING("Copyright 8/9/1993 by Glenn G. Lai") + + ALIGNDATA4 +tmp: D_LONG 0 + + SEG_TEXT + ALIGNTEXT4 +GLNAME(xf86BusToMem): + CLD + MOV_L (ESI, CONTENT(tmp)) + MOV_L (EDI, EDX) + + MOV_L (src, ESI) + MOV_L (dst, EDI) + MOV_L (len, ECX) + + CMP_L (CONST(7), ECX) + JC (quickBM) + + TEST_L (CONST(1), ESI) + JZ (BwM) + + MOVS_B + DEC_L (ECX) + +BwM: + TEST_L (CONST(2), ESI) + JZ (BlM) + + MOVS_W + DEC_L (ECX) + DEC_L (ECX) + +BlM: + MOV_L (ECX, EAX) + AND_L (CONST(3), EAX) + SHR_L (CONST(2), ECX) + REP + MOVS_L + MOV_L (EAX, ECX) +quickBM: + OR_L (ECX, ECX) + JZ (return) + REP + MOVS_B +return: + MOV_L (CONTENT(tmp), ESI) + MOV_L (EDX, EDI) + RET +/************************/ + + ALIGNTEXT4 +GLNAME(xf86MemToBus): + CLD + MOV_L (ESI, CONTENT(tmp)) + MOV_L (EDI, EDX) + + MOV_L (src, ESI) + MOV_L (dst, EDI) + MOV_L (len, ECX) + + CMP_L (CONST(7), ECX) + JC (quickMB) + + TEST_L (CONST(1), EDI) + JZ (MwB) + + MOVS_B + DEC_L (ECX) + +MwB: + TEST_L (CONST(2), EDI) + JZ (MlB) + + MOVS_W + DEC_L (ECX) + DEC_L (ECX) + +MlB: + MOV_L (ECX, EAX) + AND_L (CONST(3), EAX) + SHR_L (CONST(2), ECX) + REP + MOVS_L + MOV_L (EAX, ECX) +quickMB: + OR_L (ECX, ECX) + JZ (return) + REP + MOVS_B + + MOV_L (CONTENT(tmp), ESI) + MOV_L (EDX, EDI) + RET + diff --git a/hw/xfree86/os-support/misc/BUSmemcpy.c b/hw/xfree86/os-support/misc/BUSmemcpy.c new file mode 100644 index 000000000..acef268a1 --- /dev/null +++ b/hw/xfree86/os-support/misc/BUSmemcpy.c @@ -0,0 +1,409 @@ + +/**************************************************************************** + + For Alpha Linux, BusToMem() and MemToBus() can be simply memcpy(), BUT: + we need to prevent unaligned operations when accessing DENSE space on the BUS, + as the video memory is mmap'd that way. The below code does this. + +NOTE: we could simply use the "memcpy()" from LIBC here, but that, currently, is + not as fast. + +Thanks to Linus Torvalds for contributing this code. + +****************************************************************************/ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/misc/BUSmemcpy.c,v 1.4 2000/02/12 20:45:44 dawes Exp $ */ + +#include "X.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +#ifdef __alpha__ + +#include "compiler.h" + +/* + * The Jensen lacks dense memory, thus we have to address the bus via + * the sparse addressing scheme. These routines are only used in s3im.c + * Non time critical code uses SlowBCopy_{from/to} bus. + * + * 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 LWORD_CODING (0x18) +#define SPARSE (5) +#else +#define LWORD_CODING (0x60) +#define SPARSE (7) +#endif + +void +xf86JensenMemToBus(char *Base, long dst, long src, int count) +{ + if( ((long)src^((long)dst)) & 3) { + /* src & dst are NOT aligned to each other */ + unsigned long addr; + unsigned long low_word, high_word,last_read; + long rm,loop; + unsigned long tmp,org,org2,mask,src_org,count_org; + + src_org=src; + count_org=count; + + /* add EISA longword coding and round off*/ + addr = (long)(Base+(dst<<SPARSE) + LWORD_CODING) & ~(3<<SPARSE); + rm = (long)dst & 3; + count += rm; + + count = count_org + rm; + org = *(volatile unsigned int *)addr; + __asm__("ldq_u %0,%1" + :"=r" (low_word):"m" (*(unsigned long *)(src_org))); + src = src_org - rm; + if( count > 4 ) { + last_read = src_org+count_org - 1; + __asm__("ldq_u %0,%1" + :"=r" (high_word):"m" (*(unsigned long *)(src+4))); + __asm__("extll %1,%2,%0" + :"=r" (low_word) + :"r" (low_word), "r" ((unsigned long)(src))); + __asm__("extlh %1,%2,%0" + :"=r" (tmp) + :"r" (high_word), "r" ((unsigned long)(src))); + tmp |= low_word; + src += 4; + __asm__("mskqh %1,%2,%0" + :"=r" (tmp) + :"r" (tmp), "r" (rm)); + __asm__("mskql %1,%2,%0" + :"=r" (org2) + :"r" (org), "r" (rm)); + tmp |= org2; + + loop = (count-4) >> 2; /* loop eqv. count>=4 ; count -= 4 */ + while (loop) { + /* tmp to be stored completly -- need to read next word*/ + low_word = high_word; + *(volatile unsigned int *) (addr) = tmp; + __asm__("ldq_u %0,%1" + :"=r" (high_word):"m" (*(unsigned long*)(src+4))); + loop --; + __asm__("extll %1,%2,%0" + :"=r" (low_word) + :"r" (low_word), "r" ((unsigned long)src)); + __asm__("extlh %1,%2,%0" + :"=r" (tmp) + :"r" (high_word), "r" ((unsigned long)src)); + src += 4; + tmp |= low_word; + addr += 4<<SPARSE; + } + if ( count & 3 ) { + /* Store tmp completly, and possibly read one more word.*/ + *(volatile unsigned int *) (addr) = tmp; + __asm__("ldq_u %0,%1" + :"=r" (tmp):"m" (*((unsigned long *)(last_read)) )); + addr += 4<<SPARSE; + __asm__("extll %1,%2,%0" + :"=r" (low_word) + :"r" (high_word), "r" ((unsigned long)src)); + __asm__("extlh %1,%2,%0" + :"=r" (tmp) + :"r" (tmp), "r" ((unsigned long)src)); + tmp |= low_word; + org = *(volatile unsigned int *)addr; + + __asm__("mskql %1,%2,%0" + :"=r" (tmp) + :"r" (tmp), "r" (count&3)); + __asm__("mskqh %1,%2,%0" + :"=r" (org) + :"r" (org), "r" (count&3)); + + tmp |= org; + } + *(volatile unsigned int *) (addr) = tmp; + return; + } else { /* count > 4 */ + __asm__("ldq_u %0,%1" + :"=r" (high_word):"m" (*(unsigned long *)(src+4))); + __asm__("extll %1,%2,%0" + :"=r" (low_word) + :"r" (low_word), "r" ((unsigned long)(src))); + __asm__("extlh %1,%2,%0" + :"=r" (tmp) + :"r" (high_word), "r" ((unsigned long)(src))); + tmp |= low_word; + if( count < 4 ) { + + mask = -1; + __asm__("mskqh %1,%2,%0" + :"=r" (mask) + :"r" (mask), "r" (rm)); + __asm__("mskql %1,%2,%0" + :"=r" (mask) + :"r" (mask), "r" (count)); + tmp = (tmp & mask) | (org & ~mask); + *(volatile unsigned int *) (addr) = tmp; + return; + } else { + __asm__("mskqh %1,%2,%0" + :"=r" (tmp) + :"r" (tmp), "r" (rm)); + __asm__("mskql %1,%2,%0" + :"=r" (org2) + :"r" (org), "r" (rm)); + + tmp |= org2; + *(volatile unsigned int *) (addr) = tmp; + return; + } + } + } else { /* src & dst are aligned to each other */ + unsigned long addr; + unsigned int tmp,org,rm; + unsigned int *src_r; + + /* add EISA longword coding and round off*/ + addr = (long)(Base+(dst<<SPARSE) + LWORD_CODING) & ~(3<<SPARSE); + + src_r = (unsigned int*)((long)src & ~3L); + rm=(long)src & 3; + count += rm; + + tmp = *src_r; + org = *(volatile unsigned int *)addr; + + __asm__("mskqh %1,%2,%0" + :"=r" (tmp) + :"r" (tmp), "r" (rm)); + __asm__("mskql %1,%2,%0" + :"=r" (org) + :"r" (org), "r" (rm)); + + tmp |= org; + + while (count > 4) { + *(volatile unsigned int *) addr = tmp; + addr += 4<<SPARSE; + src_r += 1; + tmp = *src_r; + count -= 4; + } + + org = *(volatile unsigned int *)addr; + __asm__("mskql %1,%2,%0" + :"=r" (tmp) + :"r" (tmp), "r" (count)); + __asm__("mskqh %1,%2,%0" + :"=r" (org) + :"r" (org), "r" (count)); + tmp |= org; + *(volatile unsigned int *) (addr) = tmp; + } +} + +void +xf86JensenBusToMem(char *Base, char *dst, unsigned long src, int count) +{ +#if 0 + /* Optimization of BusToMem() is left as an exercise to the reader ;-) + * Consider that ldq_u/extlh/extll won't work because of the bus being + * only 4 bytes wide! + */ +#else + unsigned long addr; + long result; + + addr = (unsigned long)(Base+(src<<SPARSE)) ; + while( addr & (3<<SPARSE) ){ + if(count <= 0) return; + result = *(volatile int *) addr; + result >>= ((addr>>SPARSE) & 3) * 8; + *dst++ = (char) result; + addr += 1<<SPARSE; + count--; + } + count -=4; + while(count >= 0){ + int i; + + result = *(volatile int *) (addr+LWORD_CODING); + for(i=4;i--;) { + *dst++ = (char) result; + result >>= 8; + } + addr += 4<<SPARSE; + count -= 4; + } + count +=4; + + while( count ){ + result = *(volatile int *) addr; + result >>= ((addr>>SPARSE) & 3) * 8; + *dst++ = (char) result; + addr += 1<<SPARSE; + count--; + } +#endif +} + + +static unsigned long __memcpy(unsigned long dest, unsigned long src, int n); + +void +xf86BusToMem(unsigned char *dst, unsigned char *src, int len) +{ + __memcpy((unsigned long)dst, (unsigned long)src, len); +} +void +xf86MemToBus(unsigned char *dst, unsigned char *src, int len) +{ + if (len == sizeof(int)) + if (!(((long)src | (long)dst) & 3)) + *((unsigned int*)dst) = *((unsigned int*)(src)); + else { + int i; + if (((long)src) & 3) + i = ldl_u((unsigned int*)src); + else + i = *(unsigned int*)src; + if (((long)dst) & 3) + stl_u(i,(unsigned int*)dst); + else + *(unsigned int*)dst = i; + } + else + __memcpy((unsigned long)dst, (unsigned long)src, len); +} + +/* + * linux/arch/alpha/lib/memcpy.c + * + * Copyright (C) 1995 Linus Torvalds, used with his permission. + */ + +/* + * This is a reasonably optimized memcpy() routine. + */ + +/* + * Note that the C code is written to be optimized into good assembly. However, + * at this point gcc is unable to sanely compile "if (n >= 0)", resulting in a + * explicit compare against 0 (instead of just using the proper "blt reg, xx" or + * "bge reg, xx"). I hope alpha-gcc will be fixed to notice this eventually.. + */ + +/* + * This should be done in one go with ldq_u*2/mask/stq_u. Do it + * with a macro so that we can fix it up later.. + */ +#define ALIGN_DEST_TO8(d,s,n) \ + while (d & 7) { \ + if (n <= 0) return; \ + n--; \ + *(char *) d = *(char *) s; \ + d++; s++; \ + } + +/* + * This should similarly be done with ldq_u*2/mask/stq. The destination + * is aligned, but we don't fill in a full quad-word + */ +#define DO_REST(d,s,n) \ + while (n > 0) { \ + n--; \ + *(char *) d = *(char *) s; \ + d++; s++; \ + } + +/* + * This should be done with ldq/mask/stq. The source and destination are + * aligned, but we don't fill in a full quad-word + */ +#define DO_REST_ALIGNED(d,s,n) DO_REST(d,s,n) + +/* + * This does unaligned memory copies. We want to avoid storing to + * an unaligned address, as that would do a read-modify-write cycle. + * We also want to avoid double-reading the unaligned reads. + * + * Note the ordering to try to avoid load (and address generation) latencies. + */ +static __inline__ void __memcpy_unaligned(unsigned long d, unsigned long s, long n) +{ + ALIGN_DEST_TO8(d,s,n); + n -= 8; /* to avoid compare against 8 in the loop */ + if (n >= 0) { + unsigned long low_word, high_word; + __asm__("ldq_u %0,%1":"=r" (low_word):"m" (*(unsigned long *) s)); + do { + unsigned long tmp; + __asm__("ldq_u %0,%1":"=r" (high_word):"m" (*(unsigned long *)(s+8))); + n -= 8; + __asm__("extql %1,%2,%0" + :"=r" (low_word) + :"r" (low_word), "r" (s)); + __asm__("extqh %1,%2,%0" + :"=r" (tmp) + :"r" (high_word), "r" (s)); + s += 8; + *(unsigned long *) d = low_word | tmp; + d += 8; + low_word = high_word; + } while (n >= 0); + } + n += 8; + DO_REST(d,s,n); +} + +/* + * Hmm.. Strange. The __asm__ here is there to make gcc use a integer register + * for the load-store. I don't know why, but it would seem that using a floating + * point register for the move seems to slow things down (very small difference, + * though). + * + * Note the ordering to try to avoid load (and address generation) latencies. + */ +static __inline__ void __memcpy_aligned(unsigned long d, unsigned long s, long n) +{ + ALIGN_DEST_TO8(d,s,n); + n -= 8; + while (n >= 0) { + unsigned long tmp; + __asm__("ldq %0,%1":"=r" (tmp):"m" (*(unsigned long *) s)); + n -= 8; + s += 8; + *(unsigned long *) d = tmp; + d += 8; + } + n += 8; + DO_REST_ALIGNED(d,s,n); +} + +static unsigned long __memcpy(unsigned long dest, unsigned long src, int n) +{ + if (!((dest ^ src) & 7)) { + __memcpy_aligned(dest, src, n); + return dest; + } + __memcpy_unaligned(dest, src, n); + return dest; +} + +#else /* __alpha__ */ + +void +xf86BusToMem(unsigned char *dst, unsigned char *src, int len) +{ + memcpy(dst, src, len); +} +void +xf86MemToBus(unsigned char *dst, unsigned char *src, int len) +{ + memcpy(dst, src, len); +} + +#endif /* __alpha__ */ diff --git a/hw/xfree86/os-support/misc/Delay.c b/hw/xfree86/os-support/misc/Delay.c new file mode 100644 index 000000000..7d5dad40b --- /dev/null +++ b/hw/xfree86/os-support/misc/Delay.c @@ -0,0 +1,37 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/misc/Delay.c,v 3.3 2000/12/08 20:13:38 eich Exp $ */ + +#include "X.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +#include <time.h> + +void +xf86UDelay(long usec) +{ +#if 0 + struct timeval start, interrupt; +#else + int sigio; + + sigio = xf86BlockSIGIO(); + xf86usleep(usec); + xf86UnblockSIGIO(sigio); +#endif + +#if 0 + gettimeofday(&start,NULL); + + do { + usleep(usec); + gettimeofday(&interrupt,NULL); + + if ((usec = usec - (interrupt.tv_sec - start.tv_sec) * 1000000 + - (interrupt.tv_usec - start.tv_usec)) < 0) + break; + start = interrupt; + } while (1); +#endif +} + diff --git a/hw/xfree86/os-support/misc/IODelay.S b/hw/xfree86/os-support/misc/IODelay.S new file mode 100644 index 000000000..4c6e32f3f --- /dev/null +++ b/hw/xfree86/os-support/misc/IODelay.S @@ -0,0 +1,53 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/misc/IODelay.S,v 1.1 1999/07/10 07:24:50 dawes Exp $ */ +/******************************************************************************* + Copyright 1994 by Glenn G. Lai + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyr notice appear in all copies and that +both that copyr notice and this permission notice appear in +supporting documentation, and that the name of Glenn G. Lai not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +Glenn G. Lai DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL 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. + +Glenn G. Lai +P.O. Box 4314 +Austin, Tx 78765 +glenn@cs.utexas.edu) +7/21/94 +*******************************************************************************/ +/* $XConsortium: IODelay.s /main/4 1996/02/21 17:40:21 kaleb $ */ + +/* + * All we really need is a delay of about 40ns for I/O recovery for just + * about any occasion, but we'll be more conservative here: On a + * 100-MHz CPU, produce at least a delay of 1,000ns. + */ + +#include "assyntax.h" + + FILE("DACDelay.s") + + AS_BEGIN + + GLOBL GLNAME(xf86IODelay) + + SEG_TEXT + ALIGNTEXT4 +GLNAME(xf86IODelay): + MOV_L (CONST(100), EAX) +delay_it: + DEC_L (EAX) + JNE (delay_it) + RET + diff --git a/hw/xfree86/os-support/misc/IODelay.c b/hw/xfree86/os-support/misc/IODelay.c new file mode 100644 index 000000000..57176c5d5 --- /dev/null +++ b/hw/xfree86/os-support/misc/IODelay.c @@ -0,0 +1,24 @@ + +/* $XConsortium: IODelay.c /main/1 1996/05/07 17:13:43 kaleb $ */ +/******************************************************************************* + Stub for Alpha Linux +*******************************************************************************/ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/misc/IODelay.c,v 1.3 2000/08/04 16:13:41 eich Exp $ */ + +#include "X.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +/* + * All we really need is a delay of about 40ns for I/O recovery for just + * about any occasion, but we'll be more conservative here: On a + * 100-MHz CPU, produce at least a delay of 1,000ns. + */ +void +xf86IODelay() +{ + xf86UDelay(1); +} + diff --git a/hw/xfree86/os-support/misc/SlowBcopy.S b/hw/xfree86/os-support/misc/SlowBcopy.S new file mode 100644 index 000000000..9b6af1d69 --- /dev/null +++ b/hw/xfree86/os-support/misc/SlowBcopy.S @@ -0,0 +1,108 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/misc/SlowBcopy.S,v 1.1 1999/07/10 07:24:51 dawes Exp $ */ +/******************************************************************************* + Copyright 1994 by Glenn G. Lai + + All Rights Reserved + +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyr notice appear in all copies and that +both that copyr notice and this permission notice appear in +supporting documentation, and that the name of Glenn G. Lai not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +Glenn G. Lai DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL 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. + +Glenn G. Lai +P.O. Box 4314 +Austin, Tx 78765 +glenn@cs.utexas.edu) +7/21/94 +*******************************************************************************/ +/* $XConsortium: SlowBcopy.s /main/4 1996/02/21 17:40:52 kaleb $ */ + +/* + * Modified from the output generated by GCC + * + * Create a dependency that should be immune from the effect of register + * renaming as is commonly seen in superscalar processors. This should + * insert a minimum of 100-ns delays between reads/writes at clock rates + * up to 100 MHz---GGL + * + * Slowbcopy(char *src, char *dst, int count) + * + */ + +#include "assyntax.h" + + FILE("SlowBcopy.s") + + AS_BEGIN + +gcc2_compiled.: +___gnu_compiled_c: + + GLOBL GLNAME(xf86SlowBcopy) + + SEG_TEXT + ALIGNTEXT4 +GLNAME(xf86SlowBcopy): + PUSH_L (EBP) + MOV_L (ESP,EBP) + PUSH_L (ESI) + PUSH_L (EBX) + MOV_L (REGOFF(8,EBP),ECX) + MOV_L (REGOFF(12,EBP),EDX) + MOV_L (REGOFF(16,EBP),ESI) + XOR_L (EAX,EAX) + CMP_L (ESI,EAX) + JGE (L3) + + ALIGNTEXT4 +L5: + MOV_B (REGIND(ECX),BL) + + MOV_B (BL, BH) + MOV_B (BH, BL) + MOV_B (BL, BH) + MOV_B (BH, BL) + MOV_B (BL, BH) + MOV_B (BH, BL) + MOV_B (BL, BH) + MOV_B (BH, BL) + MOV_B (BL, BH) + MOV_B (BH, BL) + + MOV_B (BL,REGIND(EDX)) + + INC_L (ECX) + DEC_L (ECX) + INC_L (ECX) + DEC_L (ECX) + INC_L (ECX) + DEC_L (ECX) + INC_L (ECX) + DEC_L (ECX) + INC_L (ECX) + DEC_L (ECX) + + INC_L (ECX) + INC_L (EDX) + INC_L (EAX) + CMP_L (ESI,EAX) + JL (L5) +L3: + LEA_L (REGOFF(-8,EBP),ESP) + POP_L (EBX) + POP_L (ESI) + MOV_L (EBP,ESP) + POP_L (EBP) + RET + diff --git a/hw/xfree86/os-support/misc/SlowBcopy.c b/hw/xfree86/os-support/misc/SlowBcopy.c new file mode 100644 index 000000000..f705e0f42 --- /dev/null +++ b/hw/xfree86/os-support/misc/SlowBcopy.c @@ -0,0 +1,107 @@ + +/* $XConsortium: SlowBcopy.c /main/1 1996/05/07 17:14:10 kaleb $ */ +/******************************************************************************* + for Alpha Linux +*******************************************************************************/ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/misc/SlowBcopy.c,v 1.5 2001/11/19 15:44:18 tsi Exp $ */ + +/* + * Create a dependency that should be immune from the effect of register + * renaming as is commonly seen in superscalar processors. This should + * insert a minimum of 100-ns delays between reads/writes at clock rates + * up to 100 MHz---GGL + * + * Slowbcopy(char *src, char *dst, int count) + * + */ + +#include "X.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "compiler.h" + +/* The outb() isn't needed on my machine, but who knows ... -- ost */ +void +xf86SlowBcopy(unsigned char *src, unsigned char *dst, int len) +{ + while(len--) + { + *dst++ = *src++; +#if !defined(__sparc__) && !defined(__powerpc__) && !defined(__mips__) + outb(0x80, 0x00); +#endif + } +} + +#ifdef __alpha__ +/* + * The Jensen lacks dense memory, thus we have to address the bus via + * the sparse addressing scheme. Time critical code uses routines from + * BUSmemcpy.c + * + * Martin Ostermann (ost@comnets.rwth-aachen.de) - Apr.-Sep. 1996 + */ + +#ifdef linux + +unsigned long _bus_base(void); + +#ifdef TEST_JENSEN_CODE /* define to test the Sparse addressing on a non-Jensen */ +#define SPARSE (5) +#else +#define SPARSE (7) +#endif + +#define isJensen() (!_bus_base()) + +#else + +#define isJensen() 0 +#define SPARSE 0 + +#endif + +void +xf86SlowBCopyFromBus(unsigned char *src, unsigned char *dst, int count) +{ + if (isJensen()) + { + unsigned long addr; + long result; + + addr = (unsigned long) src; + while( count ){ + result = *(volatile int *) addr; + result >>= ((addr>>SPARSE) & 3) * 8; + *dst++ = (unsigned char) (0xffUL & result); + addr += 1<<SPARSE; + count--; + outb(0x80, 0x00); + } + } + else + xf86SlowBcopy(src,dst,count); +} + +void +xf86SlowBCopyToBus(unsigned char *src, unsigned char *dst, int count) +{ + if (isJensen()) + { + unsigned long addr; + + addr = (unsigned long) dst; + while(count) { + *(volatile unsigned int *) addr = (unsigned short)(*src) * 0x01010101; + src++; + addr += 1<<SPARSE; + count--; + outb(0x80, 0x00); + } + } + else + xf86SlowBcopy(src,dst,count); +} +#endif diff --git a/hw/xfree86/os-support/sco/sco_iop.c b/hw/xfree86/os-support/sco/sco_iop.c new file mode 100644 index 000000000..85b4bbd41 --- /dev/null +++ b/hw/xfree86/os-support/sco/sco_iop.c @@ -0,0 +1,124 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sco/sco_iop.c,v 1.1 2002/06/03 21:22:10 dawes Exp $ */ +/* + * Copyright 2001 by J. Kean Johnston <jkj@caldera.com> + * + * 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 J. Kean Johnston not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. J. Kean Johnston makes no + * representations about the suitability of this software for any purpose. + * It is provided "as is" without express or implied warranty. + * + * J. KEAN JOHNSTON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL J. KEAN JOHNSTON 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. + */ +/* $XConsortium$ */ + + +#include "X.h" + +#include "compiler.h" + +#define _NEED_SYSI86 +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86OSpriv.h" +#include "xf86_OSlib.h" + + +/***************************************************************************/ +/* I/O Permissions section */ +/***************************************************************************/ + +/* + * There is a right way and a wrong way of doing this. Unfortunately, we + * are forced to do it the wrong way. The right way is to be told the range + * or ranges of I/O ports the driver(s) need access to, in order to use the + * CONS_IOPERM ioctl() to grant access only to those ports we care about. + * This way we can guarantee some small level of stability because a driver + * does not have access to all ports (which would mean it could play with + * the PIT and thus affect scheduling times, or a whole slew of other + * nasty things). However, because XFree86 currently only enables or disables + * ALL port access, we need to run at IOPL 3, which basically means the + * X Server runs at the same level as the kernel. You can image why this is + * unsafe. Oh, and this is not a problem unique to OSR5, other OSes are + * affected by this as well. + * + * So, for the time being, we change our IOPL until such time as the XFree86 + * architecture is changed to allow for tighter control of I/O ports. If and + * when it is, then the CONS_ADDIOP/DELIOP ioctl() should be used to enable + * or disable access to the desired ports. + */ + +extern long sysi86 (int cmd, ...); + +static Bool IOEnabled = FALSE; + +void xf86EnableIO(void) +{ + if (IOEnabled) + return; + + if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0) + FatalError("Failed to set IOPL for extended I/O\n"); + IOEnabled = TRUE; +} + +void xf86DisableIO(void) +{ + if (!IOEnabled) + return; + + sysi86(SI86V86, V86SC_IOPL, 0); + IOEnabled = FALSE; +} + +/***************************************************************************/ +/* Interrupt Handling section */ +/***************************************************************************/ + +Bool xf86DisableInterrupts() +{ + if (!IOEnabled) { + if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0) + return FALSE; + } + +#ifdef __GNUC__ + __asm__ __volatile__("cli"); +#else + asm("cli"); +#endif /* __GNUC__ */ + + if (!IOEnabled) { + sysi86(SI86V86, V86SC_IOPL, PS_IOPL); + } + + return(TRUE); +} + +void xf86EnableInterrupts() +{ + if (!IOEnabled) { + if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0) + return; + } + +#ifdef __GNUC__ + __asm__ __volatile__("sti"); +#else + asm("sti"); +#endif /* __GNUC__ */ + + if (!IOEnabled) { + sysi86(SI86V86, V86SC_IOPL, PS_IOPL); + } +} diff --git a/hw/xfree86/os-support/shared/agp_noop.c b/hw/xfree86/os-support/shared/agp_noop.c new file mode 100644 index 000000000..c1100e67b --- /dev/null +++ b/hw/xfree86/os-support/shared/agp_noop.c @@ -0,0 +1,69 @@ +/* + * Abstraction of the AGP GART interface. Stubs for platforms without + * AGP GART support. + */ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/agp_noop.c,v 1.3 2001/05/19 00:26:46 dawes Exp $ */ + +#include "X.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "xf86OSpriv.h" + +Bool +xf86GARTCloseScreen(int screenNum) +{ + return FALSE; +} + +Bool +xf86AgpGARTSupported() +{ + return FALSE; +} + +AgpInfoPtr +xf86GetAGPInfo(int screenNum) +{ + return NULL; +} + +Bool +xf86AcquireGART(int screenNum) +{ + return FALSE; +} + +Bool +xf86ReleaseGART(int screenNum) +{ + return FALSE; +} + +int +xf86AllocateGARTMemory(int screenNum, unsigned long size, int type, + unsigned long *physical) +{ + return -1; +} + + +Bool +xf86BindGARTMemory(int screenNum, int key, unsigned long offset) +{ + return FALSE; +} + + +Bool +xf86UnbindGARTMemory(int screenNum, int key) +{ + return FALSE; +} + +Bool +xf86EnableAGP(int screenNum, CARD32 mode) +{ + return FALSE; +} diff --git a/hw/xfree86/os-support/shared/at_scancode.c b/hw/xfree86/os-support/shared/at_scancode.c new file mode 100644 index 000000000..a1529579f --- /dev/null +++ b/hw/xfree86/os-support/shared/at_scancode.c @@ -0,0 +1,74 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/at_scancode.c,v 1.1 2002/10/11 01:40:37 dawes Exp $ */ + +/* + * Copyright (c) 2002 by The XFree86 Project, Inc. + */ + +#include "xf86.h" +#include "xf86Xinput.h" +#include "xf86OSKbd.h" +#include "atKeynames.h" + +Bool +ATScancode(InputInfoPtr pInfo, int *scanCode) +{ + KbdDevPtr pKbd = (KbdDevPtr) pInfo->private; + + switch (pKbd->scanPrefix) { + case 0: + switch (*scanCode) { + case KEY_Prefix0: + case KEY_Prefix1: + pKbd->scanPrefix = *scanCode; /* special prefixes */ + return TRUE; + } + break; + case KEY_Prefix0: + pKbd->scanPrefix = 0; + switch (*scanCode) { + case KEY_KP_7: *scanCode = KEY_Home; break; /* curs home */ + case KEY_KP_8: *scanCode = KEY_Up; break; /* curs up */ + case KEY_KP_9: *scanCode = KEY_PgUp; break; /* curs pgup */ + case KEY_KP_4: *scanCode = KEY_Left; break; /* curs left */ + case KEY_KP_5: *scanCode = KEY_Begin; break; /* curs begin */ + case KEY_KP_6: *scanCode = KEY_Right; break; /* curs right */ + case KEY_KP_1: *scanCode = KEY_End; break; /* curs end */ + case KEY_KP_2: *scanCode = KEY_Down; break; /* curs down */ + case KEY_KP_3: *scanCode = KEY_PgDown; break; /* curs pgdown */ + case KEY_KP_0: *scanCode = KEY_Insert; break; /* curs insert */ + case KEY_KP_Decimal: *scanCode = KEY_Delete; break; /* curs delete */ + case KEY_Enter: *scanCode = KEY_KP_Enter; break; /* keypad enter */ + case KEY_LCtrl: *scanCode = KEY_RCtrl; break; /* right ctrl */ + case KEY_KP_Multiply: *scanCode = KEY_Print; break; /* print */ + case KEY_Slash: *scanCode = KEY_KP_Divide; break; /* keyp divide */ + case KEY_Alt: *scanCode = KEY_AltLang; break; /* right alt */ + case KEY_ScrollLock: *scanCode = KEY_Break; break; /* curs break */ + case 0x5b: *scanCode = KEY_LMeta; break; + case 0x5c: *scanCode = KEY_RMeta; break; + case 0x5d: *scanCode = KEY_Menu; break; + case KEY_F3: *scanCode = KEY_F13; break; + case KEY_F4: *scanCode = KEY_F14; break; + case KEY_F5: *scanCode = KEY_F15; break; + case KEY_F6: *scanCode = KEY_F16; break; + case KEY_F7: *scanCode = KEY_F17; break; + case KEY_KP_Plus: *scanCode = KEY_KP_DEC; break; + case 0x2A: + case 0x36: + return TRUE; + default: + xf86MsgVerb(X_INFO, 4, "Unreported Prefix0 scancode: 0x%02x\n", + *scanCode); + *scanCode += 0x78; + } + break; + case KEY_Prefix1: + pKbd->scanPrefix = (*scanCode == KEY_LCtrl) ? KEY_LCtrl : 0; + return TRUE; + case KEY_LCtrl: + pKbd->scanPrefix = 0; + if (*scanCode != KEY_NumLock) + return TRUE; + *scanCode = KEY_Pause; /* pause */ + } + return FALSE; +} diff --git a/hw/xfree86/os-support/shared/bios_mmap.c b/hw/xfree86/os-support/shared/bios_mmap.c new file mode 100644 index 000000000..ee7584222 --- /dev/null +++ b/hw/xfree86/os-support/shared/bios_mmap.c @@ -0,0 +1,160 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/bios_mmap.c,v 1.9 2001/05/23 14:46:05 alanh Exp $ */ +/* + * 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 name of David Wexelblat not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. David Wexelblat makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * DAVID WEXELBLAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL 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. + * + */ +/* $XConsortium: bios_V4mmap.c /main/4 1996/02/21 17:54:27 kaleb $ */ + +#include "X.h" + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +#ifndef MAP_FAILED +#define MAP_FAILED ((void *)-1) +#endif + +/* + * Read BIOS via mmap()ing DEV_MEM + */ + +#ifndef __alpha__ +int +xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf, + int Len) +{ + int fd; + unsigned char *ptr; + int psize; + int mlen; + + if ((fd = open(DEV_MEM, O_RDONLY)) < 0) + { + xf86Msg(X_WARNING, "xf86ReadBIOS: Failed to open %s (%s)\n", + DEV_MEM, strerror(errno)); + return(-1); + } + psize = xf86getpagesize(); + Offset += Base & (psize - 1); + Base &= ~(psize - 1); + mlen = (Offset + Len + psize - 1) & ~(psize - 1); + ptr = (unsigned char *)mmap((caddr_t)0, mlen, PROT_READ, + MAP_SHARED, fd, (off_t)Base); + if (ptr == MAP_FAILED) + { + xf86Msg(X_WARNING, "xf86ReadBIOS: %s mmap failed (%s)\n", + DEV_MEM, strerror(errno)); + close(fd); + return(-1); + } +#ifdef DEBUG + ErrorF("xf86ReadBIOS: BIOS at 0x%08x has signature 0x%04x\n", + Base, ptr[0] | (ptr[1] << 8)); +#endif + (void)memcpy(Buf, (void *)(ptr + Offset), Len); + (void)munmap((caddr_t)ptr, mlen); + (void)close(fd); + return(Len); +} + +#else /* __alpha__ */ + + /* + * We trick "mmap" into mapping BUS memory for us via BUS_BASE, + * which is the KSEG address of the start of the DENSE memory + * area. + */ + + /* + * NOTE: there prolly ought to be more validity checks and all + * re: boundaries and sizes and such... + */ + +/* + * 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 linux + +#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) +#endif + +extern unsigned long _bus_base(void); +extern unsigned long _bus_base_sparse(void); +#define BUS_BASE (isJensen ? _bus_base_sparse() : _bus_base()) +#define JENSEN_SHIFT(x) (isJensen ? ((long)x<<SPARSE) : (long)x) + +#else + +extern u_int64_t dense_base(void); +#define BUS_BASE dense_base() +#define JENSEN_SHIFT(x) ((long) x) + +#endif + +int +xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf, + int Len) +{ + caddr_t base; + int fd; + int psize; + int mlen; + + if ((fd = open(DEV_MEM, O_RDONLY)) < 0) + { + xf86Msg(X_WARNING, "xf86ReadBIOS: Failed to open %s (%s)\n", + DEV_MEM, strerror(errno)); + return(-1); + } + + psize = xf86getpagesize(); + Offset += Base & (psize - 1); + Base &= ~(psize - 1); + mlen = (Offset + Len + psize - 1) & ~(psize - 1); + base = mmap((caddr_t)0, JENSEN_SHIFT(mlen), PROT_READ, + MAP_SHARED, fd, (off_t)(JENSEN_SHIFT(Base) + BUS_BASE)); + + if (base == MAP_FAILED) + { + xf86Msg(X_WARNING, "xf86ReadBIOS: Failed to mmap %s (%s)\n", + DEV_MEM, strerror(errno)); + return(-1); + } + + xf86SlowBCopyFromBus((unsigned char *)(base+JENSEN_SHIFT(Offset)), + Buf, Len); + + munmap((caddr_t)JENSEN_SHIFT(base), JENSEN_SHIFT(mlen)); + close(fd); + return(Len); +} + +#endif /* __alpha__ */ diff --git a/hw/xfree86/os-support/shared/inout.S b/hw/xfree86/os-support/shared/inout.S new file mode 100644 index 000000000..80c47c419 --- /dev/null +++ b/hw/xfree86/os-support/shared/inout.S @@ -0,0 +1,111 @@ +/* $XConsortium: inout.s /main/6 1996/02/21 17:53:35 kaleb $ */ + + + + + +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/inout.S,v 1.1 1999/07/10 07:24:52 dawes Exp $ */ + +#include "assyntax.h" + +/* + * Make i80386 io primitives available at C-level. + */ + + FILE("inout.s") + AS_BEGIN + SEG_TEXT + +/* + *----------------------------------------------------------------------- + * inb --- + * Input one byte. + * + * Results: + * Byte in al. + *----------------------------------------------------------------------- + */ + GLOBL GLNAME(inb) +GLNAME(inb): + MOV_L (REGOFF(4,ESP),EDX) + SUB_L (EAX,EAX) + IN_B + RET + +/* + *----------------------------------------------------------------------- + * outb --- + * Output one byte. + * + * Results: + * None. + *----------------------------------------------------------------------- + */ + GLOBL GLNAME(outb) +GLNAME(outb): + MOV_L (REGOFF(4,sp),EDX) + MOV_L (REGOFF(8,sp),EAX) + OUT_B + RET +/* + *----------------------------------------------------------------------- + * inw --- + * Input one 16-bit word. + * + * Results: + * Word in ax. + *----------------------------------------------------------------------- + */ + GLOBL GLNAME(inw) +GLNAME(inw): + MOV_L (REGOFF(4,ESP),EDX) + IN_W + RET + +/* + *----------------------------------------------------------------------- + * outw --- + * Output one 16-bit word. + * + * Results: + * None. + *----------------------------------------------------------------------- + */ + GLOBL GLNAME(outw) +GLNAME(outw): + MOV_L (REGOFF(4,ESP),EDX) + MOV_L (REGOFF(8,ESP),EAX) + OUT_W + RET + +/* + *----------------------------------------------------------------------- + * inl --- + * Input one 32-bit longword. + * + * Results: + * Word in eax. + *----------------------------------------------------------------------- + */ + GLOBL GLNAME(inl) +GLNAME(inl): + MOV_L (REGOFF(4,ESP),EDX) + IN_L + RET + +/* + *----------------------------------------------------------------------- + * outl --- + * Output one 32-bit longword. + * + * Results: + * None. + *----------------------------------------------------------------------- + */ + GLOBL GLNAME(outl) +GLNAME(outl): + MOV_L (REGOFF(4,ESP),EDX) + MOV_L (REGOFF(8,ESP),EAX) + OUT_L + RET + diff --git a/hw/xfree86/os-support/shared/kbd.c b/hw/xfree86/os-support/shared/kbd.c new file mode 100644 index 000000000..0ebf729ac --- /dev/null +++ b/hw/xfree86/os-support/shared/kbd.c @@ -0,0 +1,13 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/kbd.c,v 1.2 2003/02/17 15:11:59 dawes Exp $ */ + +/* + * Copyright (c) 2001 by The XFree86 Project, Inc. + */ + +#include "xf86OSKbd.h" + +Bool +xf86OSKbdPreInit(InputInfoPtr pInfo) +{ + return FALSE; +} diff --git a/hw/xfree86/os-support/shared/kmod_noop.c b/hw/xfree86/os-support/shared/kmod_noop.c new file mode 100644 index 000000000..80f487593 --- /dev/null +++ b/hw/xfree86/os-support/shared/kmod_noop.c @@ -0,0 +1,8 @@ + +#include "xf86_OSproc.h" + +int xf86LoadKernelModule(const char *pathname) +{ + (void) pathname; + return 0; /* failure */ +} diff --git a/hw/xfree86/os-support/shared/libc_wrapper.c b/hw/xfree86/os-support/shared/libc_wrapper.c new file mode 100644 index 000000000..e72997cc3 --- /dev/null +++ b/hw/xfree86/os-support/shared/libc_wrapper.c @@ -0,0 +1,2015 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/libc_wrapper.c,v 1.88.2.2 2003/03/13 21:49:53 tsi Exp $ */ +/* + * Copyright 1997 by The XFree86 Project, Inc. + * + * 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 Orest Zborowski and David Wexelblat + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. Orest Zborowski + * and David Wexelblat make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * THE XFREE86 PROJECT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS, IN NO EVENT SHALL OREST ZBOROWSKI 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. + * + */ + +#if defined(linux) && !defined(__GLIBC__) +#undef __STRICT_ANSI__ +#endif +#include <X.h> +#include <Xmd.h> +#include <Xos.h> +#include <sys/types.h> +#include <sys/stat.h> +#if defined(__bsdi__) +#undef _POSIX_SOURCE +#undef _ANSI_SOURCE +#endif +#include <sys/time.h> +#include <math.h> +#ifdef sun +#include <ieeefp.h> +#endif +#include <stdarg.h> +#include <fcntl.h> +#include "Xfuncproto.h" +#include "os.h" +#include <ctype.h> +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <stdio.h> +#include <sys/ioctl.h> +#ifdef __UNIXOS2__ +#define NO_MMAP +#include <sys/param.h> +#endif +#ifdef HAS_SVR3_MMAPDRV +#define NO_MMAP +#ifdef SELF_CONTAINED_WRAPPER +#include <sys/at_ansi.h> +#include <sys/kd.h> +#include <sys/sysmacros.h> +#if !defined(_NEED_SYSI86) +# include <sys/immu.h> +# include <sys/region.h> +#endif +#include <sys/mmap.h> +struct kd_memloc MapDSC; +int mmapFd = -2; +#else +extern struct kd_memloc MapDSC; +extern int mmapFd; +#endif +#endif +#ifndef NO_MMAP +#include <sys/mman.h> +#ifndef MAP_FAILED +#define MAP_FAILED ((caddr_t)-1) +#endif +#endif +#if !defined(ISC) +#include <stdlib.h> +#endif + +#define NEED_XF86_TYPES +#define NEED_XF86_PROTOTYPES +#define DONT_DEFINE_WRAPPERS +#include "xf86_ansic.h" + +#ifndef SELF_CONTAINED_WRAPPER +#include "xf86.h" +#include "xf86Priv.h" +#define NO_OSLIB_PROTOTYPES +#define XF86_OS_PRIVS +#define HAVE_WRAPPER_DECLS +#include "xf86_OSlib.h" +#else +void xf86WrapperInit(void); +#endif + + +#ifndef X_NOT_POSIX +#include <dirent.h> +#else +#ifdef SYSV +#include <dirent.h> +#else +#ifdef USG +#include <dirent.h> +#else +#include <sys/dir.h> +#ifndef dirent +#define dirent direct +#endif +#endif +#endif +#endif +typedef struct dirent DIRENTRY; + +#ifdef __UNIXOS2__ +#define _POSIX_SOURCE +#endif +#ifdef ISC202 +#include <sys/types.h> +#define WIFEXITED(a) ((a & 0x00ff) == 0) /* LSB will be 0 */ +#define WEXITSTATUS(a) ((a & 0xff00) >> 8) +#define WIFSIGNALED(a) ((a & 0xff00) == 0) /* MSB will be 0 */ +#define WTERMSIG(a) (a & 0x00ff) +#else +#if defined(ISC) && !defined(_POSIX_SOURCE) +#define _POSIX_SOURCE +#include <sys/types.h> +#include <sys/wait.h> +#undef _POSIX_SOURCE +#else +#if (defined(ISC) && defined(_POSIX_SOURCE)) || defined(Lynx) || (defined (__alpha__) && defined(linux)) +#include <sys/types.h> +#endif +#include <sys/wait.h> +#endif +#endif +#ifdef Lynx +#if !defined(S_IFIFO) && defined(S_IFFIFO) +#define S_IFIFO S_IFFIFO +#endif +#endif + +/* For xf86getpagesize() */ +#if defined(linux) +#define HAS_SC_PAGESIZE +#define HAS_GETPAGESIZE +#elif defined(CSRG_BASED) +#define HAS_GETPAGESIZE +#elif defined(DGUX) +#define HAS_GETPAGESIZE +#elif defined(sun) && !defined(SVR4) +#define HAS_GETPAGESIZE +#endif +#ifdef XNO_SYSCONF +#undef _SC_PAGESIZE +#endif +#ifdef HAVE_SYSV_IPC +#include <sys/ipc.h> +#include <sys/shm.h> +#endif +#include <setjmp.h> + +#if defined(setjmp) && defined(__GNU_LIBRARY__) && \ + (!defined(__GLIBC__) || (__GLIBC__ < 2) || \ + ((__GLIBC__ == 2) && (__GLIBC_MINOR__ < 3))) +#define HAS_GLIBC_SIGSETJMP 1 +#endif + +#if 0 +#define SETBUF_RETURNS_INT +#endif + +double xf86HUGE_VAL; + +#ifndef SELF_CONTAINED_WRAPPERS +extern void xf86DisableIO(void); +#endif + +/* + * This file contains the XFree86 wrappers for libc functions that can be + * called by loadable modules + */ + +double +xf86hypot(double x, double y) +{ + return(hypot(x,y)); +} + +void +xf86qsort(void *base, xf86size_t nmemb, xf86size_t size, + int (*comp)(const void *, const void *)) +{ + qsort(base, nmemb, size, comp); +} + +/* string functions */ + +char* +xf86strcat(char* dest, const char* src) +{ + return(strcat(dest,src)); +} + +char* +xf86strchr(const char* s, int c) +{ + return strchr(s,c); +} + +int +xf86strcmp(const char* s1, const char* s2) +{ + return strcmp(s1,s2); +} + +/* Just like the BSD version. It assumes that tolower() is ANSI-compliant */ +int +xf86strcasecmp(const char* s1, const char* s2) +{ + const unsigned char *us1 = (const unsigned char *)s1; + const unsigned char *us2 = (const unsigned char *)s2; + + while (tolower(*us1) == tolower(*us2++)) + if (*us1++ == '\0') + return 0; + + return tolower(*us1) - tolower(*--us2); +} + +char* +xf86strcpy(char* dest, const char* src) +{ + return strcpy(dest,src); +} + +xf86size_t +xf86strcspn(const char* s1, const char* s2) +{ + return (xf86size_t)strcspn(s1,s2); +} + +xf86size_t +xf86strlen(const char* s) +{ + return (xf86size_t)strlen(s); +} + +char* +xf86strncat(char* dest, const char* src, xf86size_t n) +{ + return strncat(dest,src,(size_t)n); +} + +int +xf86strncmp(const char* s1, const char* s2, xf86size_t n) +{ + return strncmp(s1,s2,(size_t)n); +} + +/* Just like the BSD version. It assumes that tolower() is ANSI-compliant */ +int +xf86strncasecmp(const char* s1, const char* s2, xf86size_t n) +{ + if (n != 0) { + const unsigned char *us1 = (const unsigned char *)s1; + const unsigned char *us2 = (const unsigned char *)s2; + + do { + if (tolower(*us1) != tolower(*us2++)) + return tolower(*us1) - tolower(*--us2); + if (*us1++ == '\0') + break; + } while (--n != 0); + } + return 0; +} + +char* +xf86strncpy(char* dest, const char* src, xf86size_t n) +{ + return strncpy(dest,src,(size_t)n); +} + +char* +xf86strpbrk(const char* s1, const char* s2) +{ + return strpbrk(s1,s2); +} + +char* +xf86strrchr(const char* s, int c) +{ + return strrchr(s,c); +} + +xf86size_t +xf86strspn(const char* s1, const char* s2) +{ + return strspn(s1,s2); +} + +char* +xf86strstr(const char* s1, const char* s2) +{ + return strstr(s1,s2); +} + +char* +xf86strtok(char* s1, const char* s2) +{ + return strtok(s1,s2); +} + +char* +xf86strdup(const char* s) +{ + return xstrdup(s); +} + +int +xf86sprintf(char *s, const char *format, ...) +{ + int ret; + va_list args; + va_start(args, format); + ret = vsprintf(s, format, args); + va_end(args); + return ret; +} + +int +xf86snprintf(char *s, xf86size_t len, const char *format, ...) +{ + int ret; + va_list args; + va_start(args, format); + ret = vsnprintf(s, (size_t)len, format, args); + va_end(args); + return ret; +} + +void +xf86bzero(void* s, unsigned int n) +{ + memset(s, 0, n); +} + +#ifdef HAVE_VSSCANF +int +xf86sscanf(char *s, const char *format, ...) +#else +int +xf86sscanf(char *s, const char *format, char *a0, char *a1, char *a2, + char *a3, char *a4, char *a5, char *a6, char *a7, char *a8, + char *a9) /* limit of ten args */ +#endif +{ +#ifdef HAVE_VSSCANF + int ret; + va_list args; + va_start(args, format); + + ret = vsscanf(s,format,args); + va_end(args); + return ret; +#else + return sscanf(s, format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); +#endif +} + +/* Basic I/O */ + +int xf86errno; + +/* XXX This is not complete */ + +static int +xfToOsOpenFlags(int xfflags) +{ + int flags = 0; + + /* XXX This assumes O_RDONLY is 0 */ + if (xfflags & XF86_O_WRONLY) + flags |= O_WRONLY; + if (xfflags & XF86_O_RDWR) + flags |= O_RDWR; + if (xfflags & XF86_O_CREAT) + flags |= O_CREAT; + + return flags; +} + +int +xf86open(const char *path, int flags, ...) +{ + int fd; + va_list ap; + + va_start(ap, flags); + flags = xfToOsOpenFlags(flags); + if (flags & O_CREAT) { + /* can't request a mode_t directly on systems where mode_t + is an unsigned short */ + mode_t mode = (mode_t)va_arg(ap, unsigned int); + fd = open(path, flags, mode); + } else { + fd = open(path, flags); + } + va_end(ap); + xf86errno = xf86GetErrno(); + return fd; +} + +int +xf86close(int fd) +{ + int status = close(fd); + + xf86errno = xf86GetErrno(); + return status; +} + +long +xf86lseek(int fd, long offset, int whence) +{ + switch (whence) { + case XF86_SEEK_SET: + whence = SEEK_SET; + break; + case XF86_SEEK_CUR: + whence = SEEK_CUR; + break; + case XF86_SEEK_END: + whence = SEEK_END; + break; + } + return (long)lseek(fd, (off_t)offset, whence); +} + +int +xf86ioctl(int fd, unsigned long request, pointer argp) +{ + int status = ioctl(fd, request, argp); + + xf86errno = xf86GetErrno(); + return status; +} + +xf86ssize_t +xf86read(int fd, void *buf, xf86size_t nbytes) +{ + xf86ssize_t n = read(fd, buf, (size_t)nbytes); + + xf86errno = xf86GetErrno(); + return n; +} + +xf86ssize_t +xf86write(int fd, const void *buf, xf86size_t nbytes) +{ + xf86ssize_t n = write(fd, buf, (size_t)nbytes); + + xf86errno = xf86GetErrno(); + return n; +} + +void* +xf86mmap(void *start, xf86size_t length, int prot, + int flags, int fd, xf86size_t /* off_t */ offset) +{ +#ifndef NO_MMAP + int p=0, f=0; + void *rc; + + if (flags & XF86_MAP_FIXED) f |= MAP_FIXED; + if (flags & XF86_MAP_SHARED) f |= MAP_SHARED; + if (flags & XF86_MAP_PRIVATE) f |= MAP_PRIVATE; +#ifdef __x86_64__ + if (flags & XF86_MAP_32BIT) f |= MAP_32BIT; +#endif + if (prot & XF86_PROT_EXEC) p |= PROT_EXEC; + if (prot & XF86_PROT_READ) p |= PROT_READ; + if (prot & XF86_PROT_WRITE) p |= PROT_WRITE; + if (prot & XF86_PROT_NONE) p |= PROT_NONE; + + rc = mmap(start,(size_t)length,p,f,fd,(off_t)offset); + + xf86errno = xf86GetErrno(); + if (rc == MAP_FAILED) + return XF86_MAP_FAILED; + else + return rc; +#else +#ifdef HAS_SVR3_MMAPDRV + void *rc; +#ifdef SELF_CONTAINED_WRAPPER + if(mmapFd < 0) { + if ((mmapFd = open("/dev/mmap", O_RDWR)) == -1) { + ErrorF("Warning: failed to open /dev/mmap \n"); + xf86errno = xf86_ENOSYS; + return XF86_MAP_FAILED; + } + } +#endif + MapDSC.vaddr = (char *)start; + MapDSC.physaddr = (char *)offset; + MapDSC.length = length; + MapDSC.ioflg = 1; + + rc = (pointer)ioctl(mmapFd, MAP, &MapDSC); + xf86errno = xf86GetErrno(); + if (rc == NULL) + return XF86_MAP_FAILED; + else + return rc; +#else + ErrorF("Warning: mmap() is not supported on this platform\n"); + xf86errno = xf86_ENOSYS; + return XF86_MAP_FAILED; +#endif +#endif +} + +int +xf86munmap(void *start, xf86size_t length) +{ +#ifndef NO_MMAP + int rc = munmap(start,(size_t)length); + + xf86errno = xf86GetErrno(); + return rc; +#else +#ifdef HAS_SVR3_MMAPDRV + int rc = ioctl(mmapFd, UNMAPRM , start); + + xf86errno = xf86GetErrno(); + return rc; +#else + ErrorF("Warning: munmap() is not supported on this platform\n"); + xf86errno = xf86_ENOSYS; + return -1; +#endif +#endif +} + +int +xf86stat(const char *file_name, struct xf86stat *xfst) +{ + int rc; + struct stat st; + + rc = stat(file_name, &st); + xf86errno = xf86GetErrno(); + xfst->st_rdev = st.st_rdev; /* Not much is currently supported */ + return rc; +} + +int +xf86fstat(int fd, struct xf86stat *xfst) +{ + int rc; + struct stat st; + + rc = fstat(fd, &st); + xf86errno = xf86GetErrno(); + xfst->st_rdev = st.st_rdev; /* Not much is currently supported */ + return rc; +} + +static int +xfToOsAccessMode(int xfmode) +{ + switch(xfmode) { + case XF86_R_OK: return R_OK; + case XF86_W_OK: return W_OK; + case XF86_X_OK: return X_OK; + case XF86_F_OK: return F_OK; + } + return 0; +} + +int +xf86access(const char *pathname, int mode) +{ + int rc; + + mode = xfToOsAccessMode(mode); + rc = access(pathname, mode); + xf86errno = xf86GetErrno(); + return rc; +} + + + +/* limited stdio support */ + +#define XF86FILE_magic 0x58464856 /* "XFHV" */ + +typedef struct _xf86_file_ { + INT32 fileno; + INT32 magic; + FILE* filehnd; + char* fname; +} XF86FILE_priv; + +XF86FILE_priv stdhnd[3] = { + { 0, XF86FILE_magic, NULL, "$stdinp$" }, + { 0, XF86FILE_magic, NULL, "$stdout$" }, + { 0, XF86FILE_magic, NULL, "$stderr$" } +}; + +XF86FILE* xf86stdin = (XF86FILE*)&stdhnd[0]; +XF86FILE* xf86stdout = (XF86FILE*)&stdhnd[1]; +XF86FILE* xf86stderr = (XF86FILE*)&stdhnd[2]; + +void +xf86WrapperInit() +{ + if (stdhnd[0].filehnd == NULL) + stdhnd[0].filehnd = stdin; + if (stdhnd[1].filehnd == NULL) + stdhnd[1].filehnd = stdout; + if (stdhnd[2].filehnd == NULL) + stdhnd[2].filehnd = stderr; + xf86HUGE_VAL = HUGE_VAL; +} + +XF86FILE* +xf86fopen(const char* fn, const char* mode) +{ + XF86FILE_priv* fp; + FILE *f = fopen(fn,mode); + xf86errno = xf86GetErrno(); + if (!f) return 0; + + fp = xalloc(sizeof(XF86FILE_priv)); + fp->magic = XF86FILE_magic; + fp->filehnd = f; + fp->fileno = fileno(f); + fp->fname = xf86strdup(fn); +#ifdef DEBUG + ErrorF("xf86fopen(%s,%s) yields FILE %p XF86FILE %p\n", + fn,mode,f,fp); +#endif + return (XF86FILE*)fp; +} + +static void _xf86checkhndl(XF86FILE_priv* f,const char *func) +{ + if (!f || f->magic != XF86FILE_magic || + !f->filehnd || !f->fname) { + FatalError("libc_wrapper error: passed invalid FILE handle to %s\n", + func); + exit(42); + } +} + +int +xf86fclose(XF86FILE* f) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + int ret; + + _xf86checkhndl(fp,"xf86fclose"); + + /* somewhat bad check */ + if (fp->fileno < 3 && fp->fname[0]=='$') { + /* assume this is stdin/out/err, don't dispose */ + ret = fclose(fp->filehnd); + } else { + ret = fclose(fp->filehnd); + fp->magic = 0; /* invalidate */ + xfree(fp->fname); + xfree(fp); + } + return ret ? -1 : 0; +} + +int +xf86printf(const char *format, ...) +{ + int ret; + va_list args; + va_start(args, format); + + ret = printf(format,args); + va_end(args); + return ret; +} + +int +xf86fprintf(XF86FILE* f, const char *format, ...) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + + int ret; + va_list args; + va_start(args, format); + +#ifdef DEBUG + ErrorF("xf86fprintf for XF86FILE %p\n", fp); +#endif + _xf86checkhndl(fp,"xf86fprintf"); + + ret = vfprintf(fp->filehnd,format,args); + va_end(args); + return ret; +} + +int +xf86vfprintf(XF86FILE* f, const char *format, va_list ap) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + +#ifdef DEBUG + ErrorF("xf86vfprintf for XF86FILE %p\n", fp); +#endif + _xf86checkhndl(fp,"xf86vfprintf"); + + return vfprintf(fp->filehnd,format,ap); +} + +int +xf86vsprintf(char *s, const char *format, va_list ap) +{ + return vsprintf(s, format, ap); +} + +int +xf86vsnprintf(char *s, xf86size_t len, const char *format, va_list ap) +{ + return vsnprintf(s, (size_t)len, format, ap); +} + +#ifdef HAVE_VFSCANF +int +xf86fscanf(XF86FILE* f, const char *format, ...) +#else +int +xf86fscanf(XF86FILE* f, const char *format, char *a0, char *a1, char *a2, + char *a3, char *a4, char *a5, char *a6, char *a7, char *a8, + char *a9) /* limit of ten args */ +#endif +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + +#ifdef HAVE_VFSCANF + int ret; + va_list args; + va_start(args, format); + + _xf86checkhndl(fp,"xf86fscanf"); + + ret = vfscanf(fp->filehnd,format,args); + va_end(args); + return ret; +#else + _xf86checkhndl(fp,"xf86fscanf"); + return fscanf(fp->filehnd, format, a0, a1, a2, a3, a4, a5, a6, a7, a8, a9); +#endif +} + +char * +xf86fgets(char *buf, INT32 n, XF86FILE* f) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + + _xf86checkhndl(fp,"xf86fgets"); + return fgets(buf,(int)n,fp->filehnd); +} + +int +xf86fputs(const char *buf, XF86FILE* f) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + + _xf86checkhndl(fp,"xf86fputs"); + return fputs(buf,fp->filehnd); +} + +int +xf86getc(XF86FILE* f) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + + _xf86checkhndl(fp,"xf86getc"); + return getc(fp->filehnd); +} + +int +xf86fgetc(XF86FILE* f) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + + _xf86checkhndl(fp,"xf86fgetc"); + return fgetc(fp->filehnd); +} + +int +xf86fputc(int c,XF86FILE* f) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + + _xf86checkhndl(fp,"xf86fputc"); + return fputc(c,fp->filehnd); +} + +int +xf86fflush(XF86FILE* f) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + + _xf86checkhndl(fp,"xf86fflush"); + return fflush(fp->filehnd); +} + +xf86size_t +xf86fread(void* buf, xf86size_t sz, xf86size_t cnt, XF86FILE* f) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + +#ifdef DEBUG + ErrorF("xf86fread for XF86FILE %p\n", fp); +#endif + _xf86checkhndl(fp,"xf86fread"); + return fread(buf,(size_t)sz,(size_t)cnt,fp->filehnd); +} + +xf86size_t +xf86fwrite(const void* buf, xf86size_t sz, xf86size_t cnt, XF86FILE* f) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + + _xf86checkhndl(fp,"xf86fwrite"); + return fwrite(buf,(size_t)sz,(size_t)cnt,fp->filehnd); +} + +int +xf86fseek(XF86FILE* f, long offset, int whence) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + + _xf86checkhndl(fp,"xf86fseek"); + switch (whence) { + case XF86_SEEK_SET: + whence = SEEK_SET; + break; + case XF86_SEEK_CUR: + whence = SEEK_CUR; + break; + case XF86_SEEK_END: + whence = SEEK_END; + break; + } + return fseek(fp->filehnd,offset,whence); +} + +long +xf86ftell(XF86FILE* f) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + + _xf86checkhndl(fp,"xf86ftell"); + return ftell(fp->filehnd); +} + +#define mapnum(e) case (xf86_##e): err = e; break; + +char* +xf86strerror(int n) +{ + int err; + + switch (n) + { + case 0: err = 0; break; + mapnum (EACCES); + mapnum (EAGAIN); + mapnum (EBADF); + mapnum (EEXIST); + mapnum (EFAULT); + mapnum (EINTR); + mapnum (EINVAL); + mapnum (EISDIR); + mapnum (ELOOP); /* not POSIX 1 */ + mapnum (EMFILE); + mapnum (ENAMETOOLONG); + mapnum (ENFILE); + mapnum (ENOENT); + mapnum (ENOMEM); + mapnum (ENOSPC); + mapnum (ENOTDIR); + mapnum (EPIPE); + mapnum (EROFS); +#ifndef __UNIXOS2__ + mapnum (ETXTBSY); /* not POSIX 1 */ +#endif + mapnum (ENOTTY); + mapnum (EBUSY); + mapnum (ENODEV); + mapnum (EIO); + + default: + err = 999; + } + return strerror(err); +} + +#undef mapnum + + +/* required for portable fgetpos/fsetpos, + * use as + * XF86fpos_t* pos = xalloc(xf86fpossize()); + */ +long +xf86fpossize() +{ + return sizeof(fpos_t); +} + +int +xf86fgetpos(XF86FILE* f,XF86fpos_t* pos) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + fpos_t *ppos = (fpos_t*)pos; + + _xf86checkhndl(fp,"xf86fgetpos"); +#ifndef ISC + return fgetpos(fp->filehnd,ppos); +#else + *ppos = ftell(fp->filehnd); + if (*ppos < 0L) + return(-1); + return(0); +#endif +} + +int +xf86fsetpos(XF86FILE* f,const XF86fpos_t* pos) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + fpos_t *ppos = (fpos_t*)pos; + + /* XXX need to handle xf86errno here */ + _xf86checkhndl(fp,"xf86fsetpos"); +#ifndef ISC + return fsetpos(fp->filehnd,ppos); +#else + if (ppos == NULL) + { + errno = EINVAL; + return EOF; + } + return fseek(fp->filehnd, *ppos, SEEK_SET); +#endif +} + +void +xf86perror(const char *s) +{ + perror(s); +} + +int +xf86remove(const char *s) +{ +#ifdef _POSIX_SOURCE + return remove(s); +#else + return unlink(s); +#endif +} + +int +xf86rename(const char *old, const char *new) +{ +#ifdef _POSIX_SOURCE + return rename(old,new); +#else + int ret = link(old,new); + if (!ret) { + ret = unlink(old); + if (ret) unlink(new); + } else + ret = unlink(new); + return ret; +#endif +} + +void +xf86rewind(XF86FILE* f) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + + _xf86checkhndl(fp,"xf86fsetpos"); + rewind(fp->filehnd); +} + +void +xf86clearerr(XF86FILE* f) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + + _xf86checkhndl(fp,"xf86clearerr"); + clearerr(fp->filehnd); +} + +int +xf86feof(XF86FILE* f) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + + _xf86checkhndl(fp,"xf86feof"); + return feof(fp->filehnd); +} + +int +xf86ferror(XF86FILE* f) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + + _xf86checkhndl(fp,"xf86ferror"); + return ferror(fp->filehnd); +} + +XF86FILE* +xf86freopen(const char* fname,const char* mode,XF86FILE* fold) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)fold; + FILE *fnew; + + _xf86checkhndl(fp,"xf86freopen"); + fnew = freopen(fname,mode,fp->filehnd); + xf86errno = xf86GetErrno(); + if (!fnew) { + xf86fclose(fold); /* discard old XF86FILE structure */ + return 0; + } + /* recycle the old XF86FILE structure */ + fp->magic = XF86FILE_magic; + fp->filehnd = fnew; + fp->fileno = fileno(fnew); + fp->fname = xf86strdup(fname); +#ifdef DEBUG + ErrorF("xf86freopen(%s,%s,%p) yields FILE %p XF86FILE %p\n", + fname,mode,fold,fnew,fp); +#endif + return (XF86FILE*)fp; +} + +int +xf86setbuf(XF86FILE* f, char *buf) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + + _xf86checkhndl(fp,"xf86fsetbuf"); +#ifdef SETBUF_RETURNS_INT + return setbuf(fp->filehnd, buf); +#else + setbuf(fp->filehnd, buf); + return 0; +#endif +} + +int +xf86setvbuf(XF86FILE* f, char *buf, int mode, xf86size_t size) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + int vbufmode; + + _xf86checkhndl(fp,"xf86fsetvbuf"); + + switch (mode) { + case XF86_IONBF: + vbufmode = _IONBF; + break; + case XF86_IOLBF: + vbufmode = _IOFBF; + break; + case XF86_IOFBF: + vbufmode = _IOLBF; + break; + default: + FatalError("libc_wrapper error: mode in setvbuf incorrect\n"); + exit(42); + } + + return setvbuf(fp->filehnd,buf,vbufmode,(size_t)size); +} + +XF86FILE* +xf86tmpfile(void) +{ +#ifdef NEED_TMPFILE + return xf86fopen(tmpnam((char*)0),"w+"); +#else + XF86FILE_priv* fp; + FILE *f = tmpfile(); + xf86errno = xf86GetErrno(); + if (!f) return 0; + + fp = xalloc(sizeof(XF86FILE_priv)); + fp->magic = XF86FILE_magic; + fp->filehnd = f; + fp->fileno = fileno(f); + fp->fname = xf86strdup("*tmpfile*"); /* so that it can be xfree()'d */ +#ifdef DEBUG + ErrorF("xf86tmpfile() yields FILE %p XF86FILE %p\n",f,fp); +#endif + return (XF86FILE*)fp; +} +#endif /* HAS_TMPFILE */ + + +int +xf86ungetc(int c,XF86FILE* f) +{ + XF86FILE_priv* fp = (XF86FILE_priv*)f; + + _xf86checkhndl(fp,"xf86ungetc"); + return ungetc(c,fp->filehnd); +} + +/* Misc functions. Some are ANSI C, some are not. */ + +void +xf86usleep(usec) + unsigned long usec; +{ +#if (defined(SYSV) || defined(SVR4)) && !defined(sun) + syscall(3112, (usec) / 1000 + 1); +#else + usleep(usec); +#endif +} + +void +xf86getsecs(long * secs, long * usecs) +{ + struct timeval tv; + + X_GETTIMEOFDAY(&tv); + if (secs) + *secs = tv.tv_sec; + if (usecs) + *usecs= tv.tv_usec; + + return; +} + +int +xf86ffs(int mask) +{ + int n; + if (mask == 0) return 0; + for (n = 1; (mask & 1)==0; n++) + mask >>= 1; + return n; +} + +char * +xf86getenv(const char * a) +{ + /* Only allow this when the real and effective uids are the same */ + if (getuid() != geteuid()) + return NULL; + else + return(getenv(a)); +} + +void * +xf86bsearch(const void *key, const void *base, xf86size_t nmemb, + xf86size_t size, int (*compar)(const void *, const void *)) +{ + return bsearch(key, base, (size_t)nmemb, (size_t)size, compar); +} + +int +xf86execl(const char *pathname, const char *arg, ...) +{ +#ifndef __UNIXOS2__ + int i; + pid_t pid; + int exit_status; + char *arglist[5]; + va_list args; + va_start(args, arg); + arglist[0] = (char*)&args; + i = 1; + while (i < 5 && (arglist[i++] = va_arg(args, char *)) != NULL) + ; + va_end(args); + + if ((pid = fork()) < 0) { + ErrorF("Fork failed (%s)\n", strerror(errno)); + return -1; + } else if (pid == 0) { /* child */ + /* + * Make sure that the child doesn't inherit any I/O permissions it + * shouldn't have. It's better to put constraints on the development + * of a clock program than to give I/O permissions to a bogus program + * in someone's XF86Config file + */ +#ifndef SELF_CONTAINED_WRAPPER + xf86DisableIO(); +#endif + setuid(getuid()); +#if !defined(SELF_CONTAINED_WRAPPER) + /* set stdin, stdout to the consoleFD, and leave stderr alone */ + for (i = 0; i < 2; i++) + { + if (xf86Info.consoleFd != i) + { + close(i); + dup(xf86Info.consoleFd); + } + } +#endif + + execv(pathname, arglist); + ErrorF("Exec failed for command \"%s\" (%s)\n", + pathname, strerror(errno)); + exit(255); + } + + /* parent */ + wait(&exit_status); + if (WIFEXITED(exit_status)) + { + switch (WEXITSTATUS(exit_status)) + { + case 0: /* OK */ + return 0; + case 255: /* exec() failed */ + return(255); + default: /* bad exit status */ + ErrorF("Program \"%s\" had bad exit status %d\n", + pathname, WEXITSTATUS(exit_status)); + return(WEXITSTATUS(exit_status)); + } + } + else if (WIFSIGNALED(exit_status)) + { + ErrorF("Program \"%s\" died on signal %d\n", + pathname, WTERMSIG(exit_status)); + return(WTERMSIG(exit_status)); + } +#ifdef WIFSTOPPED + else if (WIFSTOPPED(exit_status)) + { + ErrorF("Program \"%s\" stopped by signal %d\n", + pathname, WSTOPSIG(exit_status)); + return(WSTOPSIG(exit_status)); + } +#endif + else /* should never get to this point */ + { + ErrorF("Program \"%s\" has unknown exit condition\n", + pathname); + return(1); + } +#else + return(1); +#endif /* __UNIXOS2__ Disable this crazy business for now */ +} + +void +xf86abort(void) +{ + ErrorF("Module called abort() function\n"); + abort(); +} + +void +xf86exit(int ex) +{ + ErrorF("Module called exit() function with value=%d\n",ex); + exit(ex); +} + +/* directory handling functions */ +#define XF86DIR_magic 0x78666876 /* "xfhv" */ + +typedef struct _xf86_dir_ { + DIR *dir; + INT32 magic; + XF86DIRENT *dirent; +} XF86DIR_priv; + +static void +_xf86checkdirhndl(XF86DIR_priv* f,const char *func) +{ + if (!f || f->magic != XF86DIR_magic || !f->dir || !f->dirent) { + FatalError("libc_wrapper error: passed invalid DIR handle to %s\n", + func); + exit(42); + } +} + +XF86DIR * +xf86opendir(const char *name) +{ + XF86DIR_priv *dp; + DIR *dirp; + + dirp = opendir(name); + if (!dirp) + return (XF86DIR*)0; + + dp = xalloc(sizeof(XF86DIR_priv)); + dp->magic = XF86DIR_magic; /* This time I have this, Dirk! :-) */ + dp->dir = dirp; + dp->dirent = xalloc(sizeof(struct _xf86dirent)); + + return (XF86DIR*)dp; +} + +XF86DIRENT* +xf86readdir(XF86DIR* dirp) +{ + XF86DIR_priv* dp = (XF86DIR_priv*)dirp; + DIRENTRY *de; + XF86DIRENT* xde; + int sz; + + _xf86checkdirhndl(dp,"xf86readdir"); + + de = readdir(dp->dir); + if (!de) + return (XF86DIRENT*)0; + xde = dp->dirent; + sz = strlen(de->d_name); + strncpy(xde->d_name,de->d_name, sz>_XF86NAMELEN ? (_XF86NAMELEN+1) : (sz+1)); + xde->d_name[_XF86NAMELEN] = '\0'; /* be sure to have a 0 byte */ + return xde; +} + +void +xf86rewinddir(XF86DIR* dirp) +{ + XF86DIR_priv* dp = (XF86DIR_priv*)dirp; + + _xf86checkdirhndl(dp,"xf86readdir"); + rewinddir(dp->dir); +} + +int +xf86closedir(XF86DIR* dir) +{ + XF86DIR_priv* dp = (XF86DIR_priv*)dir; + int n; + + _xf86checkdirhndl(dp,"xf86readdir"); + + n = closedir(dp->dir); + dp->magic = 0; + xfree(dp->dirent); + xfree(dp); + + return n; +} + +static mode_t +xfToOsChmodMode(xf86mode_t xfmode) +{ + mode_t mode = 0; + + if (xfmode & XF86_S_ISUID) mode |= S_ISUID; + if (xfmode & XF86_S_ISGID) mode |= S_ISGID; +#ifndef __UNIXOS2__ + if (xfmode & XF86_S_ISVTX) mode |= S_ISVTX; +#endif + if (xfmode & XF86_S_IRUSR) mode |= S_IRUSR; + if (xfmode & XF86_S_IWUSR) mode |= S_IWUSR; + if (xfmode & XF86_S_IXUSR) mode |= S_IXUSR; + if (xfmode & XF86_S_IRGRP) mode |= S_IRGRP; + if (xfmode & XF86_S_IWGRP) mode |= S_IWGRP; + if (xfmode & XF86_S_IXGRP) mode |= S_IXGRP; + if (xfmode & XF86_S_IROTH) mode |= S_IROTH; + if (xfmode & XF86_S_IWOTH) mode |= S_IWOTH; + if (xfmode & XF86_S_IXOTH) mode |= S_IXOTH; + + return mode; +} + +int +xf86chmod(const char *path, xf86mode_t xfmode) +{ + mode_t mode = xfToOsChmodMode(xfmode); + int rc = chmod(path, mode); + + xf86errno = xf86GetErrno(); + return rc; +} + +int +xf86chown(const char *path, xf86uid_t owner, xf86gid_t group) +{ +#ifndef __UNIXOS2__ + int rc = chown(path, owner, group); +#else + int rc = 0; +#endif + xf86errno = xf86GetErrno(); + return rc; +} + +xf86uid_t +xf86geteuid(void) +{ + return geteuid(); +} + +xf86gid_t +xf86getegid(void) +{ + return getegid(); +} + +int +xf86getpid(void) +{ + return getpid(); +} + +static mode_t +xfToOsMknodMode(xf86mode_t xfmode) +{ + mode_t mode = xfToOsChmodMode(xfmode); + + if (xfmode & XF86_S_IFREG) mode |= S_IFREG; + if (xfmode & XF86_S_IFCHR) mode |= S_IFCHR; +#ifndef __UNIXOS2__ + if (xfmode & XF86_S_IFBLK) mode |= S_IFBLK; +#endif + if (xfmode & XF86_S_IFIFO) mode |= S_IFIFO; + + return mode; +} + +int xf86mknod(const char *pathname, xf86mode_t xfmode, xf86dev_t dev) +{ + mode_t mode = xfToOsMknodMode(xfmode); +#ifndef __UNIXOS2__ + int rc = mknod(pathname, mode, dev); +#else + int rc = 0; +#endif + xf86errno = xf86GetErrno(); + return rc; +} + +unsigned int xf86sleep(unsigned int seconds) +{ + return sleep(seconds); +} + +int xf86mkdir(const char *pathname, xf86mode_t xfmode) +{ + mode_t mode = xfToOsChmodMode(xfmode); + int rc = mkdir(pathname, mode); + + xf86errno = xf86GetErrno(); + return rc; +} + + +/* Several math functions */ + +int +xf86abs(int x) +{ + return abs(x); +} + +double +xf86acos(double x) +{ + return acos(x); +} + +double +xf86asin(double x) +{ + return asin(x); +} + +double +xf86atan(double x) +{ + return atan(x); +} + +double +xf86atan2(double x,double y) +{ + return atan2(x,y); +} + +double +xf86atof(const char* s) +{ + return atof(s); +} + +int +xf86atoi(const char* s) +{ + return atoi(s); +} + +long +xf86atol(const char* s) +{ + return atol(s); +} + +double +xf86ceil(double x) +{ + return ceil(x); +} + +double +xf86cos(double x) +{ + return(cos(x)); +} + +double +xf86exp(double x) +{ + return(exp(x)); +} + +double +xf86fabs(double x) +{ + return(fabs(x)); +} + +int +xf86finite(double x) +{ +#ifndef QNX4 + return(finite(x)); +#else + /* XXX Replace this with something that really works. */ + return 1; +#endif +} + +double +xf86floor(double x) +{ + return floor(x); +} + +double +xf86fmod(double x,double y) +{ + return fmod(x,y); +} + +long +xf86labs(long x) +{ + return labs(x); +} + +double +xf86ldexp(double x, int exp) +{ + return ldexp(x, exp); +} + +double +xf86log(double x) +{ + return(log(x)); +} + +double +xf86log10(double x) +{ + return(log10(x)); +} + +double +xf86modf(double x,double* y) +{ + return modf(x,y); +} + +double +xf86pow(double x, double y) +{ + return(pow(x,y)); +} + +double +xf86sin(double x) +{ + return sin(x); +} + +double +xf86sqrt(double x) +{ + return(sqrt(x)); +} + +double +xf86strtod(const char *s, char **end) +{ + return strtod(s,end); +} + +long +xf86strtol(const char *s, char **end, int radix) +{ + return strtol(s,end,radix); +} + +unsigned long +xf86strtoul(const char *s, char **end,int radix) +{ + return strtoul(s,end,radix); +} + +double +xf86tan(double x) +{ + return tan(x); +} + +/* memory functions */ +void* +xf86memchr(const void* s, int c, xf86size_t n) +{ + return memchr(s,c,(size_t)n); +} + +int +xf86memcmp(const void* s1, const void* s2, xf86size_t n) +{ + return(memcmp(s1,s2,(size_t)n)); +} + +void* +xf86memcpy(void* dest, const void* src, xf86size_t n) +{ + return(memcpy(dest,src,(size_t)n)); +} + +void* +xf86memmove(void* dest, const void* src, xf86size_t n) +{ + return(memmove(dest,src,(size_t)n)); +} + +void* +xf86memset(void* s, int c, xf86size_t n) +{ + return(memset(s,c,(size_t)n)); +} + +/* ctype functions */ + +int +xf86isalnum(int c) +{ + return isalnum(c) ? 1 : 0; +} + +int +xf86isalpha(int c) +{ + return isalpha(c) ? 1 : 0; +} + +int +xf86iscntrl(int c) +{ + return iscntrl(c) ? 1 : 0; +} + +int +xf86isdigit(int c) +{ + return isdigit(c) ? 1 : 0; +} + +int +xf86isgraph(int c) +{ + return isgraph(c) ? 1 : 0; +} + +int +xf86islower(int c) +{ + return islower(c) ? 1 : 0; +} + +int +xf86isprint(int c) +{ + return isprint(c) ? 1 : 0; +} + +int +xf86ispunct(int c) +{ + return ispunct(c) ? 1 : 0; +} + +int +xf86isspace(int c) +{ + return isspace(c) ? 1 : 0; +} + +int +xf86isupper(int c) +{ + return isupper(c) ? 1 : 0; +} + +int +xf86isxdigit(int c) +{ + return isxdigit(c) ? 1 : 0; +} + +int +xf86tolower(int c) +{ + return tolower(c); +} + +int +xf86toupper(int c) +{ + return toupper(c); +} + +/* memory allocation functions */ +void* +xf86calloc(xf86size_t sz,xf86size_t n) +{ + return xcalloc(sz, n); +} + +void +xf86free(void* p) +{ + xfree(p); +} + +double +xf86frexp(double x, int *exp) +{ + return frexp(x, exp); +} + +void* +xf86malloc(xf86size_t n) +{ + return xalloc(n); +} + +void* +xf86realloc(void* p, xf86size_t n) +{ + return xrealloc(p,n); +} + +/* + * XXX This probably doesn't belong here. + */ +int +xf86getpagesize() +{ + static int pagesize = -1; + + if (pagesize != -1) + return pagesize; + +#if defined(_SC_PAGESIZE) || defined(HAS_SC_PAGESIZE) + pagesize = sysconf(_SC_PAGESIZE); +#endif +#ifdef _SC_PAGE_SIZE + if (pagesize == -1) + pagesize = sysconf(_SC_PAGE_SIZE); +#endif +#ifdef HAS_GETPAGESIZE + if (pagesize == -1) + pagesize = getpagesize(); +#endif +#ifdef PAGE_SIZE + if (pagesize == -1) + pagesize = PAGE_SIZE; +#endif + if (pagesize == -1) + FatalError("xf86getpagesize: Cannot determine page size\n"); + + return pagesize; +} + + +#define mapnum(e) case (e): return (xf86_##e) + +int +xf86GetErrno () +{ + switch (errno) + { + case 0: return 0; + mapnum (EACCES); + mapnum (EAGAIN); + mapnum (EBADF); + mapnum (EEXIST); + mapnum (EFAULT); + mapnum (EINTR); + mapnum (EINVAL); + mapnum (EISDIR); + mapnum (ELOOP); /* not POSIX 1 */ + mapnum (EMFILE); + mapnum (ENAMETOOLONG); + mapnum (ENFILE); + mapnum (ENOENT); + mapnum (ENOMEM); + mapnum (ENOSPC); + mapnum (ENOTDIR); + mapnum (EPIPE); + mapnum (EROFS); +#ifndef __UNIXOS2__ + mapnum (ETXTBSY); /* not POSIX 1 */ +#endif + mapnum (ENOTTY); + mapnum (EBUSY); + mapnum (ENODEV); + mapnum (EIO); + + default: + return (xf86_UNKNOWN); + } +} + +#undef mapnum + + + +#ifdef NEED_SNPRINTF +#include "snprintf.c" +#endif + +#ifdef HAVE_SYSV_IPC + +int +xf86shmget(xf86key_t key, int size, int xf86shmflg) +{ + int shmflg = xf86shmflg & 0777; + + if (key == XF86IPC_PRIVATE) key = IPC_PRIVATE; + + + if (xf86shmflg & XF86SHM_R) shmflg |= SHM_R; + if (xf86shmflg & XF86SHM_W) shmflg |= SHM_W; + if (xf86shmflg & XF86IPC_CREAT) shmflg |= IPC_CREAT; + if (xf86shmflg & XF86IPC_EXCL) shmflg |= IPC_EXCL; + if (xf86shmflg & XF86IPC_NOWAIT) shmflg |= IPC_NOWAIT; + return shmget((key_t) key, size, shmflg); +} + +char * +xf86shmat(int id, char *addr, int xf86shmflg) +{ + int shmflg = 0; + +#ifdef SHM_RDONLY + if (xf86shmflg & XF86SHM_RDONLY) shmflg |= SHM_RDONLY; +#endif +#ifdef SHM_RND + if (xf86shmflg & XF86SHM_RND) shmflg |= SHM_RND; +#endif +#ifdef SHM_REMAP + if (xf86shmflg & XF86SHM_REMAP) shmflg |= SHM_REMAP; +#endif + + return shmat(id,addr,shmflg); +} + +int +xf86shmdt(char *addr) +{ + return shmdt(addr); +} + +/* + * for now only implement the rmid command. + */ +int +xf86shmctl(int id, int xf86cmd, pointer buf) +{ + int cmd; + + switch (xf86cmd) { + case XF86IPC_RMID: + cmd = IPC_RMID; + break; + default: + return 0; + } + + return shmctl(id, cmd, buf); +} +#else + +int +xf86shmget(xf86key_t key, int size, int xf86shmflg) +{ + return -1; + +} + +char * +xf86shmat(int id, char *addr, int xf86shmflg) +{ + return (char *)-1; +} + +int +xf86shmctl(int id, int xf86cmd, pointer buf) +{ + return -1; +} + +int +xf86shmdt(char *addr) +{ + return -1; +} +#endif /* HAVE_SYSV_IPC */ + +int +xf86getjmptype() +{ +#ifdef HAS_GLIBC_SIGSETJMP + return 1; +#else + return 0; +#endif +} + +#ifdef HAS_GLIBC_SIGSETJMP + +int +xf86setjmp(xf86jmp_buf env) +{ +#if defined(__GLIBC__) && (__GLIBC__ >= 2) + return __sigsetjmp(env, xf86setjmp1_arg2()); +#else + return xf86setjmp1(env, xf86setjmp1_arg2()); +#endif +} + +int +xf86setjmp0(xf86jmp_buf env) +{ + FatalError("setjmp: type 0 called instead of type %d\n", xf86getjmptype()); +} + +#if !defined(__GLIBC__) || (__GLIBC__ < 2) /* libc5 */ + +int +xf86setjmp1(xf86jmp_buf env, int arg2) +{ + __sigjmp_save((void *)env, arg2); + return __setjmp((void *)env); +} + +#endif + +#else /* HAS_GLIBC_SIGSETJMP */ + +int +xf86setjmp1(xf86jmp_buf env, int arg2) +{ + FatalError("setjmp: type 1 called instead of type %d\n", xf86getjmptype()); +} + +#endif /* HAS_GLIBC_SIGSETJMP */ + +int +xf86setjmp1_arg2() +{ + return 1; +} + +int +xf86setjmperror(xf86jmp_buf env) +{ + FatalError("setjmp: don't know how to handle setjmp() type %d\n", + xf86getjmptype()); +} + diff --git a/hw/xfree86/os-support/shared/pm_noop.c b/hw/xfree86/os-support/shared/pm_noop.c new file mode 100644 index 000000000..fc02b3a20 --- /dev/null +++ b/hw/xfree86/os-support/shared/pm_noop.c @@ -0,0 +1,18 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/pm_noop.c,v 1.1 2000/02/13 03:36:11 dawes Exp $ */ + +/* Stubs for the OS-support layer power-management functions. */ + +#include "X.h" +#include "os.h" +#include "xf86.h" +#include "xf86Priv.h" +#define XF86_OS_PRIVS +#include "xf86_OSproc.h" + +PMClose +xf86OSPMOpen(void) +{ + return NULL; +} + + diff --git a/hw/xfree86/os-support/shared/sigio.c b/hw/xfree86/os-support/shared/sigio.c new file mode 100644 index 000000000..077c566a6 --- /dev/null +++ b/hw/xfree86/os-support/shared/sigio.c @@ -0,0 +1,277 @@ +/* sigio.c -- Support for SIGIO handler installation and removal + * Created: Thu Jun 3 15:39:18 1999 by faith@precisioninsight.com + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Authors: Rickard E. (Rik) Faith <faith@valinux.com> + * + * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/sigio.c,v 1.14 2002/05/05 19:18:14 herrb Exp $ + * + */ + + +#ifdef XFree86Server +# include "X.h" +# include "xf86.h" +# include "xf86drm.h" +# include "xf86Priv.h" +# include "xf86_OSlib.h" +# include "xf86drm.h" +# include "inputstr.h" +#else +# include <unistd.h> +# include <signal.h> +# include <fcntl.h> +# include <sys/time.h> +# include <errno.h> +# include <stdio.h> +# include <string.h> +# define SYSCALL(call) while(((call) == -1) && (errno == EINTR)) +#endif + +/* + * Linux libc5 defines FASYNC, but not O_ASYNC. Don't know if it is + * functional or not. + */ +#if defined(FASYNC) && !defined(O_ASYNC) +# define O_ASYNC FASYNC +#endif + +#ifdef MAX_DEVICES +/* MAX_DEVICES represents the maximimum number of input devices usable + * at the same time plus one entry for DRM support. + */ +# define MAX_FUNCS (MAX_DEVICES + 1) +#else +# define MAX_FUNCS 16 +#endif + +typedef struct _xf86SigIOFunc { + void (*f) (int, void *); + int fd; + void *closure; +} Xf86SigIOFunc; + +static Xf86SigIOFunc xf86SigIOFuncs[MAX_FUNCS]; +static int xf86SigIOMax; +static int xf86SigIOMaxFd; +static fd_set xf86SigIOMask; + +/* + * SIGIO gives no way of discovering which fd signalled, select + * to discover + */ +static void +xf86SIGIO (int sig) +{ + int i; + fd_set ready; + struct timeval to; + int r; + + ready = xf86SigIOMask; + to.tv_sec = 0; + to.tv_usec = 0; + SYSCALL (r = select (xf86SigIOMaxFd, &ready, 0, 0, &to)); + for (i = 0; r > 0 && i < xf86SigIOMax; i++) + if (xf86SigIOFuncs[i].f && FD_ISSET (xf86SigIOFuncs[i].fd, &ready)) + { + (*xf86SigIOFuncs[i].f)(xf86SigIOFuncs[i].fd, + xf86SigIOFuncs[i].closure); + r--; + } +#ifdef XFree86Server + if (r > 0) { + xf86Msg(X_ERROR, "SIGIO %d descriptors not handled\n", r); + } +#endif +} + +static int +xf86IsPipe (int fd) +{ + struct stat buf; + + if (fstat (fd, &buf) < 0) + return 0; + return S_ISFIFO(buf.st_mode); +} + +int +xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *closure) +{ + struct sigaction sa; + struct sigaction osa; + int i; + int blocked; + + for (i = 0; i < MAX_FUNCS; i++) + { + if (!xf86SigIOFuncs[i].f) + { + if (xf86IsPipe (fd)) + return 0; + blocked = xf86BlockSIGIO(); + if (fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) | O_ASYNC) == -1) { +#ifdef XFree86Server + xf86Msg(X_WARNING, "fcntl(%d, O_ASYNC): %s\n", + fd, strerror(errno)); +#else + fprintf(stderr,"fcntl(%d, O_ASYNC): %s\n", + fd, strerror(errno)); +#endif + xf86UnblockSIGIO(blocked); + return 0; + } + if (fcntl(fd, F_SETOWN, getpid()) == -1) { +#ifdef XFree86Server + xf86Msg(X_WARNING, "fcntl(%d, F_SETOWN): %s\n", + fd, strerror(errno)); +#else + fprintf(stderr,"fcntl(%d, F_SETOWN): %s\n", + fd, strerror(errno)); +#endif + return 0; + } + sigemptyset(&sa.sa_mask); + sigaddset(&sa.sa_mask, SIGIO); + sa.sa_flags = 0; + sa.sa_handler = xf86SIGIO; + sigaction(SIGIO, &sa, &osa); + xf86SigIOFuncs[i].fd = fd; + xf86SigIOFuncs[i].closure = closure; + xf86SigIOFuncs[i].f = f; + if (i >= xf86SigIOMax) + xf86SigIOMax = i+1; + if (fd >= xf86SigIOMaxFd) + xf86SigIOMaxFd = fd + 1; + FD_SET (fd, &xf86SigIOMask); + xf86UnblockSIGIO(blocked); + return 1; + } + /* Allow overwriting of the closure and callback */ + else if (xf86SigIOFuncs[i].fd == fd) + { + xf86SigIOFuncs[i].closure = closure; + xf86SigIOFuncs[i].f = f; + return 1; + } + } + return 0; +} + +int +xf86RemoveSIGIOHandler(int fd) +{ + struct sigaction sa; + struct sigaction osa; + int i; + int max; + int maxfd; + int ret; + + max = 0; + maxfd = -1; + ret = 0; + for (i = 0; i < MAX_FUNCS; i++) + { + if (xf86SigIOFuncs[i].f) + { + if (xf86SigIOFuncs[i].fd == fd) + { + xf86SigIOFuncs[i].f = 0; + xf86SigIOFuncs[i].fd = 0; + xf86SigIOFuncs[i].closure = 0; + FD_CLR (fd, &xf86SigIOMask); + ret = 1; + } + else + { + max = i + 1; + if (xf86SigIOFuncs[i].fd >= maxfd) + maxfd = xf86SigIOFuncs[i].fd + 1; + } + } + } + if (ret) + { + fcntl(fd, F_SETFL, fcntl(fd, F_GETFL) & ~O_ASYNC); + xf86SigIOMax = max; + xf86SigIOMaxFd = maxfd; + if (!max) + { + sigemptyset(&sa.sa_mask); + sigaddset(&sa.sa_mask, SIGIO); + sa.sa_flags = 0; + sa.sa_handler = SIG_DFL; + sigaction(SIGIO, &sa, &osa); + } + } + return ret; +} + +int +xf86BlockSIGIO (void) +{ + sigset_t set, old; + + sigemptyset (&set); + sigaddset (&set, SIGIO); + sigprocmask (SIG_BLOCK, &set, &old); + return sigismember (&old, SIGIO); +} + +void +xf86UnblockSIGIO (int wasset) +{ + sigset_t set; + + if (!wasset) + { + sigemptyset (&set); + sigaddset (&set, SIGIO); + sigprocmask (SIG_UNBLOCK, &set, NULL); + } +} + +#ifdef XFree86Server +void +xf86AssertBlockedSIGIO (char *where) +{ + sigset_t set, old; + + sigemptyset (&set); + sigprocmask (SIG_BLOCK, &set, &old); + if (!sigismember (&old, SIGIO)) + xf86Msg (X_ERROR, "SIGIO not blocked at %s\n", where); +} + +/* XXX This is a quick hack for the benefit of xf86SetSilkenMouse() */ + +int +xf86SIGIOSupported (void) +{ + return 1; +} + +#endif diff --git a/hw/xfree86/os-support/shared/sigiostubs.c b/hw/xfree86/os-support/shared/sigiostubs.c new file mode 100644 index 000000000..0fdebda1d --- /dev/null +++ b/hw/xfree86/os-support/shared/sigiostubs.c @@ -0,0 +1,54 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/sigiostubs.c,v 1.2 1999/10/14 04:25:01 dawes Exp $ */ + +#ifdef XFree86Server +# include "X.h" +# include "xf86.h" +# include "xf86drm.h" +# include "xf86Priv.h" +# include "xf86_OSlib.h" +# include "xf86drm.h" +#else +# include <unistd.h> +# include <signal.h> +# include <fcntl.h> +# include <sys/time.h> +# include <errno.h> +#endif + +int +xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *closure) +{ + return 0; +} + +int +xf86RemoveSIGIOHandler(int fd) +{ + return 0; +} + +int +xf86BlockSIGIO (void) +{ + return 0; +} + +void +xf86UnblockSIGIO (int wasset) +{ +} + +#ifdef XFree86Server +void +xf86AssertBlockedSIGIO (char *where) +{ +} +#endif + +/* XXX This is a quick hack for the benefit of xf86SetSilkenMouse() */ +Bool +xf86SIGIOSupported () +{ + return FALSE; +} + diff --git a/hw/xfree86/os-support/shared/stdPci.c b/hw/xfree86/os-support/shared/stdPci.c new file mode 100644 index 000000000..b21acabcc --- /dev/null +++ b/hw/xfree86/os-support/shared/stdPci.c @@ -0,0 +1,19 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/stdPci.c,v 3.2 1999/12/06 03:55:13 robin Exp $ */ + +#include "X.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86Privstr.h" +#include "xf86Pci.h" +#define NEED_OS_RAC_PROTOS +#include "xf86_OSlib.h" + +#ifndef HAVE_PCI_SIZE_FUNC +#define xf86StdGetPciSizeFromOS xf86GetPciSizeFromOS +#endif + +Bool +xf86StdGetPciSizeFromOS(PCITAG tag, int index, int* bits) +{ + return FALSE; +} diff --git a/hw/xfree86/os-support/shared/stdResource.c b/hw/xfree86/os-support/shared/stdResource.c new file mode 100644 index 000000000..5aae4ae9d --- /dev/null +++ b/hw/xfree86/os-support/shared/stdResource.c @@ -0,0 +1,146 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/stdResource.c,v 1.20 2002/01/25 21:56:20 tsi Exp $ */ + +/* Standard resource information code */ + +#include "X.h" +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86Privstr.h" +#include "xf86Pci.h" +#define NEED_OS_RAC_PROTOS +#include "xf86_OSlib.h" +#include "xf86Resources.h" + +/* Avoid Imakefile changes */ +#include "bus/Pci.h" + +#ifdef USESTDRES +#define xf86StdBusAccWindowsFromOS xf86BusAccWindowsFromOS +#define xf86StdAccResFromOS xf86AccResFromOS +#define xf86StdPciBusAccWindowsFromOS xf86PciBusAccWindowsFromOS +#define xf86StdIsaBusAccWindowsFromOS xf86IsaBusAccWindowsFromOS + +resRange PciAvoid[] = {_PCI_AVOID_PC_STYLE, _END}; +#endif + +#ifdef INCLUDE_XF86_NO_DOMAIN + +resPtr +xf86StdBusAccWindowsFromOS(void) +{ + /* Fallback is to allow addressing of all memory space */ + resPtr ret = NULL; + resRange range; + + RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + + /* Fallback is to allow addressing of all I/O space */ + RANGE(range, 0x00000000, 0x0000ffff, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); + return ret; +} + +resPtr +xf86StdPciBusAccWindowsFromOS(void) +{ + /* Fallback is to allow addressing of all memory space */ + resPtr ret = NULL; + resRange range; + + RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + + /* Fallback is to allow addressing of all I/O space */ + RANGE(range, 0x00000000, 0x0000ffff, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); + return ret; +} + +#ifdef INCLUDE_UNUSED + +resPtr +xf86StdIsaBusAccWindowsFromOS(void) +{ + /* Fallback is to allow addressing of all memory space */ + resPtr ret = NULL; + resRange range; + + RANGE(range, 0x00000000, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + + /* Fallback is to allow addressing of all I/O space */ + RANGE(range, 0x00000000, 0x0000ffff, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); + return ret; +} + +#endif /* INCLUDE_UNUSED */ + +resPtr +xf86StdAccResFromOS(resPtr ret) +{ + resRange range; + + /* + * Fallback is to claim the following areas: + * + * 0x00000000 - 0x0009ffff low 640k host memory + * 0x000c0000 - 0x000effff location of VGA and other extensions ROMS + * 0x000f0000 - 0x000fffff system BIOS + * 0x00100000 - 0x3fffffff low 1G - 1MB host memory + * 0xfec00000 - 0xfecfffff default I/O APIC config space + * 0xfee00000 - 0xfeefffff default Local APIC config space + * 0xffe00000 - 0xffffffff high BIOS area (should this be included?) + * + * reference: Intel 440BX AGP specs + * + * The two APIC spaces appear to be BX-specific and should be dealt with + * elsewhere. + */ + + /* Fallback is to claim 0x0 - 0x9ffff and 0x100000 - 0x7fffffff */ + RANGE(range, 0x00000000, 0x0009ffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x000c0000, 0x000effff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x000f0000, 0x000fffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x00100000, 0x3fffffff, + ResExcMemBlock | ResBios | ResEstimated); + ret = xf86AddResToList(ret, &range, -1); +#if 0 + RANGE(range, 0xfec00000, 0xfecfffff, ResExcMemBlock | ResBios); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0xfee00000, 0xfeefffff, ResExcMemBlock | ResBios); + ret = xf86AddResToList(ret, &range, -1); +#endif + RANGE(range, 0xffe00000, 0xffffffff, ResExcMemBlock | ResBios); + ret = xf86AddResToList(ret, &range, -1); + + /* + * Fallback would be to claim well known ports in the 0x0 - 0x3ff range + * along with their sparse I/O aliases, but that's too imprecise. Instead + * claim a bare minimum here. + */ + RANGE(range, 0x00000000, 0x000000ff, ResExcIoBlock); /* For mainboard */ + ret = xf86AddResToList(ret, &range, -1); + + /* + * At minimum, the top and bottom resources must be claimed, so that + * resources that are (or appear to be) unallocated can be relocated. + */ +/* RANGE(range, 0x00000000, 0x00000000, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0xffffffff, 0xffffffff, ResExcMemBlock); + ret = xf86AddResToList(ret, &range, -1); + RANGE(range, 0x00000000, 0x00000000, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); */ + RANGE(range, 0x0000ffff, 0x0000ffff, ResExcIoBlock); + ret = xf86AddResToList(ret, &range, -1); + + /* XXX add others */ + return ret; +} + +#endif /* INCLUDE_XF86_NO_DOMAIN */ diff --git a/hw/xfree86/os-support/shared/vidmem.c b/hw/xfree86/os-support/shared/vidmem.c new file mode 100644 index 000000000..872cd7aa9 --- /dev/null +++ b/hw/xfree86/os-support/shared/vidmem.c @@ -0,0 +1,270 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/vidmem.c,v 1.15 2001/10/28 03:34:02 tsi Exp $ */ +/* + * Copyright 1993-1999 by The XFree86 Project, Inc + * + */ + +#include "X.h" +#include "input.h" +#include "scrnintstr.h" + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" +#include "xf86OSpriv.h" + +/* + * This file contains the common part of the video memory mapping functions + */ + +/* + * Get a piece of the ScrnInfoRec. At the moment, this is only used to hold + * the MTRR option information, but it is likely to be expanded if we do + * auto unmapping of memory at VT switch. + * + */ + +typedef struct { + unsigned long physBase; + unsigned long size; + pointer virtBase; + pointer mtrrInfo; + int flags; +} MappingRec, *MappingPtr; + +typedef struct { + int numMappings; + MappingPtr * mappings; + Bool mtrrEnabled; + MessageType mtrrFrom; + Bool mtrrOptChecked; + ScrnInfoPtr pScrn; +} VidMapRec, *VidMapPtr; + +static int vidMapIndex = -1; + +#define VIDMAPPTR(p) ((VidMapPtr)((p)->privates[vidMapIndex].ptr)) + +static VidMemInfo vidMemInfo = {FALSE, }; +static VidMapRec vidMapRec = {0, NULL, TRUE, X_DEFAULT, FALSE, NULL}; + +static VidMapPtr +getVidMapRec(int scrnIndex) +{ + VidMapPtr vp; + ScrnInfoPtr pScrn; + + if ((scrnIndex < 0) || + !(pScrn = xf86Screens[scrnIndex])) + return &vidMapRec; + + if (vidMapIndex < 0) + vidMapIndex = xf86AllocateScrnInfoPrivateIndex(); + + if (VIDMAPPTR(pScrn) != NULL) + return VIDMAPPTR(pScrn); + + vp = pScrn->privates[vidMapIndex].ptr = xnfcalloc(sizeof(VidMapRec), 1); + vp->mtrrEnabled = TRUE; /* default to enabled */ + vp->mtrrFrom = X_DEFAULT; + vp->mtrrOptChecked = FALSE; + vp->pScrn = pScrn; + return vp; +} + +static MappingPtr +newMapping(VidMapPtr vp) +{ + vp->mappings = xnfrealloc(vp->mappings, sizeof(MappingPtr) * + (vp->numMappings + 1)); + vp->mappings[vp->numMappings] = xnfcalloc(sizeof(MappingRec), 1); + return vp->mappings[vp->numMappings++]; +} + +static MappingPtr +findMapping(VidMapPtr vp, pointer vbase, unsigned long size) +{ + int i; + + for (i = 0; i < vp->numMappings; i++) { + if (vp->mappings[i]->virtBase == vbase && + vp->mappings[i]->size == size) + return vp->mappings[i]; + } + return NULL; +} + +static void +removeMapping(VidMapPtr vp, MappingPtr mp) +{ + int i, found = 0; + + for (i = 0; i < vp->numMappings; i++) { + if (vp->mappings[i] == mp) { + found = 1; + xfree(vp->mappings[i]); + } else if (found) { + vp->mappings[i - 1] = vp->mappings[i]; + } + } + vp->numMappings--; + vp->mappings[vp->numMappings] = NULL; +} + +enum { OPTION_MTRR }; +static const OptionInfoRec opts[] = +{ + { OPTION_MTRR, "mtrr", OPTV_BOOLEAN, {0}, FALSE }, + { -1, NULL, OPTV_NONE, {0}, FALSE } +}; + +static void +checkMtrrOption(VidMapPtr vp) +{ + if (!vp->mtrrOptChecked && vp->pScrn && vp->pScrn->options != NULL) { + OptionInfoPtr options; + + options = xnfalloc(sizeof(opts)); + (void)memcpy(options, opts, sizeof(opts)); + xf86ProcessOptions(vp->pScrn->scrnIndex, vp->pScrn->options, + options); + if (xf86GetOptValBool(options, OPTION_MTRR, &vp->mtrrEnabled)) + vp->mtrrFrom = X_CONFIG; + xfree(options); + vp->mtrrOptChecked = TRUE; + } +} + +void +xf86MakeNewMapping(int ScreenNum, int Flags, unsigned long Base, unsigned long Size, pointer Vbase) +{ + VidMapPtr vp; + MappingPtr mp; + + vp = getVidMapRec(ScreenNum); + mp = newMapping(vp); + mp->physBase = Base; + mp->size = Size; + mp->virtBase = Vbase; + mp->flags = Flags; +} + +void +xf86InitVidMem(void) +{ + if (!vidMemInfo.initialised) { + memset(&vidMemInfo, 0, sizeof(VidMemInfo)); + xf86OSInitVidMem(&vidMemInfo); + } +} + +pointer +xf86MapVidMem(int ScreenNum, int Flags, unsigned long Base, unsigned long Size) +{ + pointer vbase = NULL; + VidMapPtr vp; + MappingPtr mp; + + if (((Flags & VIDMEM_FRAMEBUFFER) && + (Flags & (VIDMEM_MMIO | VIDMEM_MMIO_32BIT)))) + FatalError("Mapping memory with more than one type\n"); + + xf86InitVidMem(); + if (!vidMemInfo.initialised || !vidMemInfo.mapMem) + return NULL; + + vbase = vidMemInfo.mapMem(ScreenNum, Base, Size, Flags); + + if (!vbase || vbase == (pointer)-1) + return NULL; + + vp = getVidMapRec(ScreenNum); + mp = newMapping(vp); + mp->physBase = Base; + mp->size = Size; + mp->virtBase = vbase; + mp->flags = Flags; + + /* + * Check the "mtrr" option even when MTRR isn't supported to avoid + * warnings about unrecognised options. + */ + checkMtrrOption(vp); + + if (vp->mtrrEnabled && vidMemInfo.setWC) { + if (Flags & (VIDMEM_MMIO | VIDMEM_MMIO_32BIT)) + mp->mtrrInfo = + vidMemInfo.setWC(ScreenNum, Base, Size, FALSE, + vp->mtrrFrom); + else if (Flags & VIDMEM_FRAMEBUFFER) + mp->mtrrInfo = + vidMemInfo.setWC(ScreenNum, Base, Size, TRUE, + vp->mtrrFrom); + } + return vbase; +} + +void +xf86UnMapVidMem(int ScreenNum, pointer Base, unsigned long Size) +{ + VidMapPtr vp; + MappingPtr mp; + + if (!vidMemInfo.initialised || !vidMemInfo.unmapMem) { + xf86DrvMsg(ScreenNum, X_WARNING, + "xf86UnMapVidMem() called before xf86MapVidMem()\n"); + return; + } + + vp = getVidMapRec(ScreenNum); + mp = findMapping(vp, Base, Size); + if (!mp) { + xf86DrvMsg(ScreenNum, X_WARNING, + "xf86UnMapVidMem: cannot find region for [%p,0x%lx]\n", + Base, Size); + return; + } + if (vp->mtrrEnabled && vidMemInfo.undoWC && mp) + vidMemInfo.undoWC(ScreenNum, mp->mtrrInfo); + + vidMemInfo.unmapMem(ScreenNum, Base, Size); + removeMapping(vp, mp); +} + +Bool +xf86CheckMTRR(int ScreenNum) +{ + VidMapPtr vp = getVidMapRec(ScreenNum); + + /* + * Check the "mtrr" option even when MTRR isn't supported to avoid + * warnings about unrecognised options. + */ + checkMtrrOption(vp); + + if (vp->mtrrEnabled && vidMemInfo.setWC) + return TRUE; + + return FALSE; +} + +Bool +xf86LinearVidMem() +{ + xf86InitVidMem(); + return vidMemInfo.linearSupported; +} + +void +xf86MapReadSideEffects(int ScreenNum, int Flags, pointer base, + unsigned long Size) +{ + if (!(Flags & VIDMEM_READSIDEEFFECT)) + return; + + if (!vidMemInfo.initialised || !vidMemInfo.readSideEffects) + return; + + vidMemInfo.readSideEffects(ScreenNum, base, Size); +} + diff --git a/hw/xfree86/os-support/shared/xf86Axp.c b/hw/xfree86/os-support/shared/xf86Axp.c new file mode 100644 index 000000000..24d31db59 --- /dev/null +++ b/hw/xfree86/os-support/shared/xf86Axp.c @@ -0,0 +1,20 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/xf86Axp.c,v 1.2 2000/11/06 21:57:11 dawes Exp $ */ + +#include "xf86Axp.h" + +axpParams xf86AXPParams[] = { + {SYS_NONE, 0, 0, 0}, + {TSUNAMI, 0, 0, 0}, + {LCA, 1<<24,0xf8000000, 1UL << 32}, + {APECS, 1<<24,0xf8000000, 1UL << 32}, + {T2, 0,0xFC000000, 1UL << 31}, + {T2_GAMMA, 0,0xFC000000, 1UL << 31}, + {CIA, 0,0xE0000000, 1UL << 34}, + {MCPCIA, 0,0xf8000000, 1UL << 31}, + {JENSEN, 0, 0xE000000, 1UL << 32}, + {POLARIS, 0, 0, 0}, + {PYXIS, 0, 0, 0}, + {PYXIS_CIA, 0,0xE0000000, 1UL << 34}, + {IRONGATE, 0, 0, 0} +}; + diff --git a/hw/xfree86/os-support/shared/xf86Axp.h b/hw/xfree86/os-support/shared/xf86Axp.h new file mode 100644 index 000000000..e63619e3a --- /dev/null +++ b/hw/xfree86/os-support/shared/xf86Axp.h @@ -0,0 +1,32 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/shared/xf86Axp.h,v 1.3 2001/02/15 19:46:03 eich Exp $ */ + +#ifndef _XF86_AXP_H_ +#define _XF86_AXP_H_ + +typedef enum { + SYS_NONE, + TSUNAMI, + LCA, + APECS, + T2, + T2_GAMMA, + CIA, + MCPCIA, + JENSEN, + POLARIS, + PYXIS, + PYXIS_CIA, + IRONGATE +} axpDevice; + +typedef struct { + axpDevice id; + unsigned long hae_thresh; + unsigned long hae_mask; + unsigned long size; +} axpParams; + +extern axpParams xf86AXPParams[]; + +#endif + diff --git a/hw/xfree86/os-support/solaris/apSolaris.shar b/hw/xfree86/os-support/solaris/apSolaris.shar new file mode 100644 index 000000000..33cecdc4d --- /dev/null +++ b/hw/xfree86/os-support/solaris/apSolaris.shar @@ -0,0 +1,768 @@ +#!/bin/sh +# $XFree86: xc/programs/Xserver/hw/xfree86/etc/apSolaris.shar,v 1.3 2002/10/04 19:45:33 tsi Exp $ +# This is a shell archive (produced by GNU sharutils 4.2c). +# To extract the files from this archive, save it to some FILE, remove +# everything before the `!/bin/sh' line above, then type `sh FILE'. +# +# Made on 2002-10-04 13:41 MDT by <root@abcyxhiz>. +# Source directory was `/archives'. +# +# Existing files will *not* be overwritten unless `-c' is specified. +# This format requires very little intelligence at unshar time. +# "if test", "echo", "mkdir", and "sed" may be needed. +# +# This shar contains: +# length mode name +# ------ ---------- ------------------------------------------ +# 1521 -rw-r--r-- aperture/Makefile +# 1659 -rw-r--r-- aperture/README +# 7557 -rw-r--r-- aperture/aperture.c +# 450 -rw-r--r-- aperture/aperture.conf +# 87 -rw-r--r-- aperture/devlink.tab +# 1062 -rw-r--r-- aperture/Makefile.sun4u +# +echo=echo +shar_tty= shar_n= shar_c=' +' +mkdir _sh09806 || ( echo 'failed to create locking directory' '_sh09806'; exit 1 ) +# ============= aperture/Makefile ============== +if test ! -d 'aperture'; then + $echo $echo_n 'x -' 'aperture: '$echo_c + if mkdir 'aperture'; then $echo 'created'; else $echo 'failed to create'; fi +fi +if test -f 'aperture/Makefile' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'aperture/Makefile' '(file already exists)' +else + $echo 'x -' extracting 'aperture/Makefile' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'aperture/Makefile' && +X# +X# File: makefile for aperture Framebuffer Driver +X# Author: Doug Anson (danson@lgc.com) +X# Date: 2/15/94 +X# Modified: David Holland (davidh@use.com) +X# Date: 2/23/94 +X# - Changed name, and debugging structure +X# Modified: Marc Aurele La France (tsi@xfree86.org) +X# Date: 2001.06.08 +X# - SPARC support, cleanup and turf aptest. +X# +X# >>NOTE<< Have a look at Makefile.sun4u for sun4u specifics. +X# +X# GNU gcc compiler +XCC=gcc +XCFLGS=-fno-builtin -Wall -O3 +X +X# +X# Proworks compiler +X#CC=/opt/SUNWspro/bin/cc +X#CFLGS=-Xa -xnolib -xO3 +X +X# +X# Debug error reporting +X#DEBUG_FLG= +X#DEBUG_FLG=-DAPERTURE_DEBUG +X +X# +X# Files and object declarations +XKERNEL_FLGS=-D_KERNEL -DSUNDDI +XCFLAGS= $(CFLGS) $(KERNEL_FLGS) $(DEBUG_FLG) +XCFILES= aperture.c +XOBJS= aperture.o +XDRIVER= aperture +X +X# +X# Make rules +Xall: $(DRIVER) +X +X$(DRIVER): $(OBJS) +X @if [ -f "Makefile.`uname -m`" ]; then \ +X make -f Makefile.`uname -m` $(DRIVER); \ +X else \ +X rm -f $(DRIVER); \ +X ld -r -o $(DRIVER) $(OBJS); \ +X fi +X +Xinstall: $(DRIVER) +X @if [ -f "Makefile.`uname -m`" ]; then \ +X make -f Makefile.`uname -m` install; \ +X else \ +X cp aperture.conf /kernel/drv; \ +X cp $(DRIVER) /kernel/drv; \ +X fi +X +Xadd_drv: +X @if [ -f "Makefile.`uname -m`" ]; then \ +X make -f Makefile.`uname -m` add_drv; \ +X else \ +X add_drv /kernel/drv/aperture; \ +X fi +X +Xclean: +X rm -f *% *.BAK $(OBJS) $(DRIVER) core +X +X.SUFFIXES: .i +X +X.c.i: +X $(CC) -E $(CFLAGS) $*.c > $@ +X +X.c.o: +X @if [ -f "Makefile.`uname -m`" ]; then \ +X make -f Makefile.`uname -m` $@; \ +X else \ +X rm -f $@; \ +X $(CC) -c $(CFLAGS) $*.c -o $@; \ +X fi +SHAR_EOF + : || $echo 'restore of' 'aperture/Makefile' 'failed' +fi +# ============= aperture/README ============== +if test -f 'aperture/README' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'aperture/README' '(file already exists)' +else + $echo 'x -' extracting 'aperture/README' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'aperture/README' && +XFramebuffer apperture driver. +X +XThis driver was written to provide a device that, unlike /dev/mem, allows +Xmmap()'ing of ranges beyond installed memory. +X +XThe original x86-based version of this driver was the corroborative work of +XDoug Anson (danson@lgc.com), and David Holland (davidh@use.com). It has since +Xbeen rewritten to also work on sun4u machines. +X +X +XInstallation instructions: +X +X1) Check the Makefile, for appropriate CC, and CFLAGS definitions. Compiling +X with APERTURE_DEBUG defined means the driver will generate reams of +X debugging output. You'll probably want to leave this off... +X +X2) type 'make'. The driver and test program should compile with out any +X problems. There also should not be any warning messages. +X +X3) Become 'root'. +X +X4) type 'make install' and 'make add_drv'. The screen should look something +X like this: +X +X # make install +X cp aperture aperture.conf /kernel/drv +X # make add_drv +X add_drv /kernel/drv/aperture +X +X On a sun4u machine this will mention the /kernel/drv/sparcv9 directory +X instead of /kernel/drv. +X +X This installs the driver in the system. +X +X5) While as root modify the file /etc/devlink.tab, adding these lines: +X +X# The following entry is for the framebuffer driver +Xtype=ddi_pseudo;name=aperture fbs/\M0 +X +X Add that line exactly as shown. You may also simply add the +X contents of the devlink.tab file supplied to /etc/devlink.tab. +X It contains the lines as well. (Yes, that is a tab between +X aperture, and fbs, not spaces - very important) +X +X6) Perform a reconfiguration boot of the system. +X +X # touch /reconfigure +X # init 6 +X +XBug reports, questions, suggestions, etc can be sent to xfree86@xfree86.org. +SHAR_EOF + : || $echo 'restore of' 'aperture/README' 'failed' +fi +# ============= aperture/aperture.c ============== +if test -f 'aperture/aperture.c' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'aperture/aperture.c' '(file already exists)' +else + $echo 'x -' extracting 'aperture/aperture.c' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'aperture/aperture.c' && +X/* +X * Copyright (C) 2001 The XFree86 Project, Inc. All Rights Reserved. +X * +X * Permission is hereby granted, free of charge, to any person obtaining a copy +X * of this software and associated documentation files (the "Software"), to +X * deal in the Software without restriction, including without limitation the +X * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +X * sell copies of the Software, and to permit persons to whom the Software is +X * furnished to do so, subject to the following conditions: +X * +X * The above copyright notice and this permission notice shall be included in +X * all copies or substantial portions of the Software. +X * +X * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +X * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +X * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +X * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +X * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +X * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +X * +X * Except as contained in this notice, the name of the XFree86 Project shall +X * not be used in advertising or otherwise to promote the sale, use or other +X * dealings in this Software without prior written authorization from the +X * XFree86 Project. +X */ +X +X/* +X * Aperture driver for Solaris. +X */ +X +X#include <sys/conf.h> +X#include <sys/ddi.h> +X#include <sys/modctl.h> +X#include <sys/open.h> +X#include <sys/stat.h> +X#include <sys/sunddi.h> +X +X#define DEV_IDENT "aperture" +X#define DEV_BANNER "XFree86 aperture driver" +X +X#ifndef D_64BIT +X#define D_64BIT 0 +X#endif +X +X#ifndef NULL +X#define NULL ((void *)0) +X#endif +X +X/* +X * open(9E) +X */ +X/*ARGSUSED*/ +Xstatic int +Xaperture_open +X( +X#ifdef __STDC__ +X dev_t *devp, +X int flag, +X int typ, +X struct cred *cred +X#endif +X) +X#ifndef __STDC__ +X dev_t *devp; +X int flag; +X int typ; +X struct cred *cred; +X#endif +X{ +X int error; +X +X#ifdef APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": entering open()\n"); +X +X#endif +X +X if ((typ != OTYP_CHR) || (getminor(*devp))) +X error = EINVAL; +X else +X error = 0; +X +X#ifdef APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": leaving open() = %d\n", error); +X +X#endif +X +X return error; +X} +X +X/* +X * mmap(9E) +X */ +X/*ARGSUSED*/ +Xstatic int +Xaperture_mmap +X( +X#ifdef __STDC__ +X dev_t dev, +X off_t off, +X int prot +X#endif +X) +X#ifndef __STDC__ +X dev_t dev; +X off_t off; +X int prot; +X#endif +X{ +X pfn_t pf; +X int error; +X +X#ifdef APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": entering mmap(0x%016lx)\n", off); +X +X#endif +X +X pf = btop((unsigned long)off); +X +X /* Deal with mmap(9E) interface limits */ +X error = (int)pf; +X if ((error < 0) || (pf != (pfn_t)error)) +X error = -1; +X +X#ifdef APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": leaving mmap() = 0x%08lx", error); +X +X#endif +X +X return error; +X} +X +Xstatic struct cb_ops aperture_cb_ops = +X{ +X aperture_open, /* open */ +X nulldev, /* close */ +X nodev, /* strategy */ +X nodev, /* print */ +X nodev, /* dump */ +X nodev, /* read */ +X nodev, /* write */ +X nodev, /* ioctl */ +X nodev, /* devmap */ +X aperture_mmap, /* mmap */ +X ddi_segmap, /* segmap */ +X nochpoll, /* poll */ +X ddi_prop_op, /* cb_prop_op */ +X 0, /* streamtab */ +X D_NEW | D_MP | D_64BIT /* Driver compatibility flag */ +X}; +X +X +Xstatic dev_info_t *aperture_dip; /* private copy of devinfo pointer */ +X +X/* +X * getinfo(9E) +X */ +X/*ARGSUSED*/ +Xstatic int +Xaperture_getinfo +X( +X#ifdef __STDC__ +X dev_info_t *dip, +X ddi_info_cmd_t infocmd, +X void *arg, +X void **result +X#endif +X) +X#ifndef __STDC__ +X dev_info_t *dip; +X ddi_info_cmd_t infocmd; +X void *arg; +X void **result; +X#endif +X{ +X int error; +X +X#ifdef APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": entering getinfo()\n"); +X +X#endif +X +X switch (infocmd) { +X case DDI_INFO_DEVT2DEVINFO: +X *result = aperture_dip; +X error = DDI_SUCCESS; +X break; +X case DDI_INFO_DEVT2INSTANCE: +X *result = NULL; +X error = DDI_SUCCESS; +X break; +X default: +X error = DDI_FAILURE; +X } +X +X#ifdef APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": leaving getinfo() = %d\n", error); +X +X#endif +X +X return error; +X} +X +X/* +X * identify(9E) +X */ +X/*ARGSUSED*/ +Xstatic int +Xaperture_identify +X( +X#ifdef __STDC__ +X dev_info_t *dip +X#endif +X) +X#ifndef __STDC__ +X dev_info_t *dip; +X#endif +X{ +X int error; +X +X#ifdef APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": entering identify()\n"); +X +X#endif +X +X if (strcmp(ddi_get_name(dip), DEV_IDENT)) +X error = DDI_NOT_IDENTIFIED; +X else +X error = DDI_IDENTIFIED; +X +X#ifdef APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": leaving identify() = %d\n", error); +X +X#endif +X +X return error; +X} +X +X/* +X * attach(9E) +X */ +X/*ARGSUSED*/ +Xstatic int +Xaperture_attach +X( +X#ifdef __STDC__ +X dev_info_t *dip, +X ddi_attach_cmd_t cmd +X#endif +X) +X#ifndef __STDC__ +X dev_info_t *dip; +X ddi_attach_cmd_t cmd; +X#endif +X{ +X int error; +X +X#ifdef APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": entering attach()\n"); +X +X#endif +X +X if (cmd != DDI_ATTACH) +X { +X +X#ifdef APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": not attach(, DDI_ATTACH)\n"); +X +X#endif +X +X error = DDI_FAILURE; +X } +X else +X { +X error = ddi_create_minor_node(dip, ddi_get_name(dip), S_IFCHR, +X (minor_t)ddi_get_instance(dip), +X NULL, NODESPECIFIC_DEV); +X +X if (error == DDI_SUCCESS) +X { +X aperture_dip = dip; +X ddi_report_dev(dip); +X } +X } +X +X#ifdef APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": leaving attach() = %d\n", error); +X +X#endif +X +X return error; +X} +X +X/* +X * detach(9E) +X */ +Xstatic int +Xaperture_detach +X( +X#ifdef __STDC__ +X dev_info_t *dip, +X ddi_detach_cmd_t cmd +X#endif +X) +X#ifndef __STDC__ +X dev_info_t *dip; +X ddi_detach_cmd_t cmd; +X#endif +X{ +X int error; +X +X#ifdef APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": entering detach()\n"); +X +X#endif +X +X if (cmd != DDI_DETACH) +X { +X error = DDI_FAILURE; +X } +X else +X { +X ddi_remove_minor_node(dip, NULL); +X aperture_dip = NULL; +X error = DDI_SUCCESS; +X } +X +X#if APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": leaving detach() = %d\n", error); +X +X#endif +X +X return error; +X} +X +X +Xstatic struct dev_ops aperture_ops = +X{ +X DEVO_REV, /* revision */ +X 0, /* refcnt */ +X aperture_getinfo, /* getinfo */ +X aperture_identify, /* identify */ +X nulldev, /* probe */ +X aperture_attach, /* attach */ +X aperture_detach, /* detach */ +X nodev, /* reset */ +X &aperture_cb_ops, /* driver operations */ +X NULL /* bus operations */ +X}; +X +X +Xstatic struct modldrv modldrv = +X{ +X &mod_driverops, /* mod_ops structure pointer */ +X DEV_BANNER, /* driver banner string */ +X &aperture_ops, /* dev_ops structure pointer */ +X}; +X +X +Xstatic struct modlinkage modlinkage = +X{ +X MODREV_1, /* module API revision */ +X { +X &modldrv, /* module driver structure pointer */ +X NULL /* list termination */ +X } +X}; +X +X +X/* +X * _init(9E) +X */ +Xint +X_init +X( +X#ifdef __STDC__ +X void +X#endif +X) +X{ +X int error; +X +X#ifdef APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": entering _init()\n"); +X +X#endif +X +X error = mod_install(&modlinkage); +X +X#ifdef APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": leaving _init() = %d\n", error); +X +X#endif +X +X return error; +X} +X +X/* +X * _info(9E) +X */ +Xint +X_info +X( +X#ifdef __STDC__ +X struct modinfo *modinfop +X#endif +X) +X#ifndef __STDC__ +X struct modinfo *modinfop; +X#endif +X{ +X int error; +X +X#ifdef APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": entering _info()\n"); +X +X#endif +X +X error = mod_info(&modlinkage, modinfop); +X +X#ifdef APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": leaving _info() = %d\n", error); +X +X#endif +X +X return error; +X} +X +X/* +X * _fini(9E) +X */ +Xint +X_fini +X( +X#ifdef __STDC__ +X void +X#endif +X) +X{ +X int error; +X +X#ifdef APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": entering _fini()\n"); +X +X#endif +X +X error = mod_remove(&modlinkage); +X +X#ifdef APERTURE_DEBUG +X +X cmn_err(CE_CONT, DEV_IDENT ": leaving _fini() = %d\n", error); +X +X#endif +X +X return error; +X} +SHAR_EOF + : || $echo 'restore of' 'aperture/aperture.c' 'failed' +fi +# ============= aperture/aperture.conf ============== +if test -f 'aperture/aperture.conf' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'aperture/aperture.conf' '(file already exists)' +else + $echo 'x -' extracting 'aperture/aperture.conf' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'aperture/aperture.conf' && +X# +X# Copyright 1994 Doug Anson, danson@lgc.com & David Holland, davidh@use.com +X# +X# File: aperture.conf +X# Author: Doug Anson (danson@lgc.com) +X# +X# Modified: David Holland (davidh@use.com) +X# Log: Change comments 02/23/94 +X# Change defaults/comments 09/25/94 +X# +X# Modified: Marc Aurele La France (tsi@xfree86.org) +X# Log: SPARC changes 2001.09 +X# +X# Purpose: This conf file is used by the aperture driver. +X# +Xname="aperture" parent="pseudo"; +SHAR_EOF + : || $echo 'restore of' 'aperture/aperture.conf' 'failed' +fi +# ============= aperture/devlink.tab ============== +if test -f 'aperture/devlink.tab' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'aperture/devlink.tab' '(file already exists)' +else + $echo 'x -' extracting 'aperture/devlink.tab' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'aperture/devlink.tab' && +X# The following entry is for the aperture driver +Xtype=ddi_pseudo;name=aperture fbs/\M0 +SHAR_EOF + : || $echo 'restore of' 'aperture/devlink.tab' 'failed' +fi +# ============= aperture/Makefile.sun4u ============== +if test -f 'aperture/Makefile.sun4u' && test "$first_param" != -c; then + $echo 'x -' SKIPPING 'aperture/Makefile.sun4u' '(file already exists)' +else + $echo 'x -' extracting 'aperture/Makefile.sun4u' '(text)' + sed 's/^X//' << 'SHAR_EOF' > 'aperture/Makefile.sun4u' && +X# +X# File: makefile for aperture Framebuffer Driver +X# Author: Doug Anson (danson@lgc.com) +X# Date: 2/15/94 +X# Modified: David Holland (davidh@use.com) +X# Date: 2/23/94 +X# - Changed name, and debugging structure +X# Modified: Marc Aurele La France (tsi@xfree86.org) +X# Date: 2001.06.08 +X# - SPARC support, cleanup and turf aptest. +X# +X +X# +X# GNU gcc compiler, version 3.2 or later +X# +XCC=gcc +XCFLGS=-fno-builtin -Wall -O3 -m64 +X +X# +X# Proworks compiler +X#CC=/opt/SUNWspro/bin/cc +X#CFLGS=-Xa -xarch=v9 -xnolib -xO3 +X +X# +X# Debug error reporting +X#DEBUG_FLG= +X#DEBUG_FLG=-DAPERTURE_DEBUG +X +X# +X# Files and object declarations +XKERNEL_FLGS=-D_KERNEL -DSUNDDI +XCFLAGS= $(CFLGS) $(KERNEL_FLGS) $(DEBUG_FLG) +XCFILES= aperture.c +XOBJS= aperture.o +XDRIVER= aperture +X +X# +X# Make rules +Xall: $(DRIVER) +X +X$(DRIVER): $(OBJS) +X rm -f $(DRIVER) +X ld -r -o $(DRIVER) $(OBJS) +X +Xinstall: $(DRIVER) +X cp aperture.conf /kernel/drv +X cp $(DRIVER) /kernel/drv/sparcv9 +X +Xadd_drv: +X add_drv /kernel/drv/sparcv9/aperture +X +Xclean: +X rm -f *% *.BAK $(OBJS) $(DRIVER) core +X +X.SUFFIXES: .i +X +X.c.i: +X $(CC) -E $(CFLAGS) $*.c > $@ +SHAR_EOF + : || $echo 'restore of' 'aperture/Makefile.sun4u' 'failed' +fi +$echo $shar_n 'x -' 'lock directory' "\`_sh09806': " $shar_c +if rm -fr _sh09806; then + $echo 'removed' +else + $echo 'failed to remove' +fi +exit 0 diff --git a/hw/xfree86/os-support/solaris/sun_bios.c b/hw/xfree86/os-support/solaris/sun_bios.c new file mode 100644 index 000000000..d1c79888b --- /dev/null +++ b/hw/xfree86/os-support/solaris/sun_bios.c @@ -0,0 +1,100 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_bios.c,v 1.2 2001/10/28 03:34:02 tsi Exp $ */ +/* + * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany + * Copyright 1993 by David Wexelblat <dwex@goblin.org> + * Copyright 1999 by David Holland <davidh@iquest.net> + * + * 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 the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS 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 i386 +#define _NEED_SYSI86 +#endif +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +#ifndef MAP_FAILED +#define MAP_FAILED ((void *)-1) +#endif + +extern char *apertureDevName; + +/* + * Read BIOS via mmap()ing physical memory. + */ +int +xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf, + int Len) +{ + int fd; + unsigned char *ptr; + char solx86_vtname[20]; + int psize; + int mlen; + + /* + * Solaris 2.1 x86 SVR4 (10/27/93) + * The server must treat the virtual terminal device file + * as the standard SVR4 /dev/pmem. By default, then used VT + * is considered the "default" file to open. + * + * Solaris 2.8 x86 (7/26/99) - DWH + * + * Use /dev/xsvc for everything. + */ + psize = xf86getpagesize(); + Offset += Base & (psize - 1); + Base &= ~(psize - 1); + mlen = (Offset + Len + psize - 1) & ~(psize - 1); +#if defined(i386) && !defined(__SOL8__) + if (Base >= 0xA0000 && Base + mlen < 0xFFFFF && xf86Info.vtno >= 0) + sprintf(solx86_vtname, "/dev/vt%02d", xf86Info.vtno); + else +#endif + { + if (!xf86LinearVidMem()) + FatalError("xf86ReadBIOS: Could not mmap BIOS" + " [a=%x]\n", Base); + sprintf(solx86_vtname, apertureDevName); + } + + if ((fd = open(solx86_vtname, O_RDONLY)) < 0) + { + xf86Msg(X_WARNING, "xf86ReadBIOS: Failed to open %s (%s)\n", + solx86_vtname, strerror(errno)); + return(-1); + } + ptr = (unsigned char *)mmap((caddr_t)0, mlen, PROT_READ, + MAP_SHARED, fd, (off_t)Base); + if (ptr == MAP_FAILED) + { + xf86Msg(X_WARNING, "xf86ReadBIOS: %s mmap failed " + "[0x%05x, 0x%04x]\n", + solx86_vtname, Base, mlen); + close(fd); + return -1; + } + + (void)memcpy(Buf, (void *)(ptr + Offset), Len); + (void)munmap((caddr_t)ptr, mlen); + (void)close(fd); + + return Len; +} diff --git a/hw/xfree86/os-support/solaris/sun_init.c b/hw/xfree86/os-support/solaris/sun_init.c new file mode 100644 index 000000000..b08529a00 --- /dev/null +++ b/hw/xfree86/os-support/solaris/sun_init.c @@ -0,0 +1,375 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_init.c,v 1.6 2002/06/06 13:49:34 dawes Exp $ */ +/* + * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany + * Copyright 1993 by David Wexelblat <dwex@goblin.org> + * Copyright 1999 by David Holland <davidh@iquest.net> + * + * 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 the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, AND IN NO + * EVENT SHALL THE COPYRIGHT HOLDERS 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. + */ + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +static Bool KeepTty = FALSE; +static Bool Protect0 = FALSE; +#ifdef HAS_USL_VTS +static int VTnum = -1; +static int xf86StartVT = -1; +#endif + +static char fb_dev[PATH_MAX] = "/dev/console"; + +void +xf86OpenConsole(void) +{ +#ifdef HAS_USL_VTS + int fd, i; + struct vt_mode VT; + struct vt_stat vtinfo; + int FreeVTslot; + MessageType from = X_PROBED; +#endif + + 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); + } + } + +#ifdef HAS_USL_VTS + + /* + * Setup the virtual terminal manager + */ + if (VTnum != -1) + { + xf86Info.vtno = VTnum; + from = X_CMDLINE; + } + else + { + if ((fd = open("/dev/vt00",O_RDWR,0)) < 0) + FatalError("xf86OpenConsole: Cannot open /dev/vt00 (%s)\n", + strerror(errno)); + + if (ioctl(fd, VT_GETSTATE, &vtinfo) < 0) + FatalError("xf86OpenConsole: Cannot determine current VT\n"); + + xf86StartVT = vtinfo.v_active; + + /* + * There is a SEVERE problem with x86's VT's. The VT_OPENQRY + * ioctl() will panic the entire system if all 8 (7 VT's+Console) + * terminals are used. The only other way I've found to determine + * if there is a free VT is to try activating all the the available + * VT's and see if they all succeed - if they do, there there is no + * free VT, and the Xserver cannot continue without panic'ing the + * system. (It's ugly, but it seems to work.) Note there is a + * possible race condition here. + * + * David Holland 2/23/94 + */ + + FreeVTslot = 0; + for (i = 7; (i >= 0) && !FreeVTslot; i--) + if (ioctl(fd, VT_ACTIVATE, i) != 0) + FreeVTslot = 1; + + if (!FreeVTslot || + (ioctl(fd, VT_OPENQRY, &xf86Info.vtno) < 0) || + (xf86Info.vtno == -1)) + FatalError("xf86OpenConsole: Cannot find a free VT\n"); + + close(fd); + } + + xf86Msg(from, "using VT number %d\n\n", xf86Info.vtno); + + sprintf(fb_dev, "/dev/vt%02d", xf86Info.vtno); /* Solaris 2.1 x86 */ + +#endif /* HAS_USL_VTS */ + + if (!KeepTty) + setpgrp(); + + if (((xf86Info.consoleFd = open(fb_dev, O_RDWR | O_NDELAY, 0)) < 0)) + FatalError("xf86OpenConsole: Cannot open %s (%s)\n", + fb_dev, strerror(errno)); + +#ifdef HAS_USL_VTS + + /* Change ownership of the vt */ + chown(fb_dev, 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 re-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 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); + +#endif /* HAS_USL_VTS */ + + } +} + +void +xf86CloseConsole(void) +{ +#ifdef HAS_USL_VTS + struct vt_mode VT; +#endif +#if defined(__SOL8__) || !defined(i386) + int tmp; +#endif + +#ifndef i386 + + if (!xf86DoProbe && !xf86DoConfigure) { + int fd; + + /* + * Wipe out framebuffer just like the non-SI Xsun server does. This + * could be improved by saving framebuffer contents in + * xf86OpenConsole() above and restoring them here. Also, it's unclear + * at this point whether this should be done for all framebuffers in + * the system, rather than only the console. + */ + if ((fd = open("/dev/fb", O_RDWR, 0)) < 0) { + xf86Msg(X_WARNING, + "xf86CloseConsole(): unable to open framebuffer (%s)\n", + strerror(errno)); + } else { + struct fbgattr fbattr; + + if ((ioctl(fd, FBIOGATTR, &fbattr) < 0) && + (ioctl(fd, FBIOGTYPE, &fbattr.fbtype) < 0)) { + xf86Msg(X_WARNING, + "xf86CloseConsole(): unable to retrieve framebuffer" + " attributes (%s)\n", strerror(errno)); + } else { + pointer fbdata; + + fbdata = mmap(NULL, fbattr.fbtype.fb_size, + PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (fbdata == MAP_FAILED) { + xf86Msg(X_WARNING, + "xf86CloseConsole(): unable to mmap framebuffer" + " (%s)\n", strerror(errno)); + } else { + (void)memset(fbdata, 0, fbattr.fbtype.fb_size); + (void)munmap(fbdata, fbattr.fbtype.fb_size); + } + } + + close(fd); + } + } + +#endif + +#ifdef HAS_USL_VTS + + /* + * Solaris 2.1 x86 doesn't seem to "switch" back to the console when the VT + * is relinquished and its mode is reset to auto. Also, Solaris 2.1 seems + * to associate vt00 with the console so I've opened the "console" back up + * and made it the active vt again in text mode and then closed it. There + * must be a better hack for this but I'm not aware of one at this time. + * + * Doug Anson 11/6/93 + * danson@lgc.com + * + * Fixed - 12/5/93 - David Holland - davidh@dorite.use.com + * Did the whole thing similarly to the way linux does it + */ + + /* Reset the display back to text mode */ + ioctl(xf86Info.consoleFd, KDSETMODE, KD_TEXT); + if (ioctl(xf86Info.consoleFd, VT_GETMODE, &VT) != -1) + { + VT.mode = VT_AUTO; /* Set default vt handling */ + ioctl(xf86Info.consoleFd, VT_SETMODE, &VT); + } + + /* Activate the VT that X was started on */ + ioctl(xf86Info.consoleFd, VT_ACTIVATE, xf86StartVT); + +#endif /* HAS_USL_VTS */ + + close(xf86Info.consoleFd); + +#if defined(__SOL8__) || !defined(i386) + + /* + * This probably shouldn't be here. However, there is no corresponding + * xf86CloseKbd() routine - DWH + */ + + /* Set the keyboard into "indirect" mode and turn off even translation */ + tmp = 0; + (void) ioctl(xf86Info.kbdFd, KIOCSDIRECT, &tmp); + tmp = TR_ASCII; + (void) ioctl(xf86Info.kbdFd, KIOCTRANS, &tmp); + + close(xf86Info.kbdFd); + +#endif +} + +int +xf86ProcessArgument(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; + } + + /* + * 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; + } + +#ifdef HAS_USL_VTS + + if ((argv[i][0] == 'v') && (argv[i][1] == 't')) + { + if (sscanf(argv[i], "vt%2d", &VTnum) == 0) + { + UseMsg(); + VTnum = -1; + return 0; + } + + return 1; + } + +#endif /* HAS_USL_VTS */ + +#if defined(__SOL8__) || !defined(i386) + + if ((i + 1) < argc) { + if (!strcmp(argv[i], "-dev")) { + strncpy(fb_dev, argv[i+1], PATH_MAX); + fb_dev[PATH_MAX - 1] = '\0'; + return 2; + } + + if (!strcmp(argv[i], "-ar1")) { + xf86Info.kbdDelay = atoi(argv[i + 1]) * 1000; + return 2; + } + + if (!strcmp(argv[i], "-ar2")) { + xf86Info.kbdRate = atoi(argv[i + 1]) * 1000; + return 2; + } + } + +#endif + + return 0; +} + +void xf86UseMsg() +{ +#ifdef HAS_USL_VTS + ErrorF("vtXX Use the specified VT number\n"); +#endif +#if defined(__SOL8__) || !defined(i386) + ErrorF("-dev <fb> Framebuffer device\n"); + ErrorF("-ar1 <float> Set autorepeat initiate time (sec)\n"); + ErrorF(" (if not using XKB)\n"); + ErrorF("-ar2 <float> Set autorepeat interval time (sec)\n"); + ErrorF(" (if not using XKB)\n"); +#endif + ErrorF("-keeptty Don't detach controlling tty\n"); + ErrorF(" (for debugging only)\n"); +} diff --git a/hw/xfree86/os-support/solaris/sun_inout.s b/hw/xfree86/os-support/solaris/sun_inout.s new file mode 100644 index 000000000..e8f03d0e8 --- /dev/null +++ b/hw/xfree86/os-support/solaris/sun_inout.s @@ -0,0 +1,124 @@ +/ $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_inout.s,v 1.1 2001/05/28 02:42:31 tsi Exp $ +/ +/ Copyright 1994-2001 The XFree86 Project, Inc. All Rights Reserved. +/ +/ Permission is hereby granted, free of charge, to any person obtaining a copy +/ of this software and associated documentation files (the "Software"), to deal +/ in the Software without restriction, including without limitation the rights +/ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +/ copies of the Software, and to permit persons to whom the Software is +/ furnished to do so, subject to the following conditions: +/ +/ The above copyright notice and this permission notice shall be included in +/ all copies or substantial portions of the Software. +/ +/ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +/ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +/ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +/ XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +/ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +/ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/ +/ Except as contained in this notice, the name of the XFree86 Project shall not +/ be used in advertising or otherwise to promote the sale, use or other +/ dealings in this Software without prior written authorization from the +/ XFree86 Project. +/ +/ +/ File: sun_inout.s +/ +/ Purpose: Provide inb(), inw(), inl(), outb(), outw(), outl() functions +/ for Solaris x86 using the ProWorks compiler by SunPro +/ +/ Author: Installed into XFree86 SuperProbe by Doug Anson (danson@lgc.com) +/ Portions donated to XFree86 by Steve Dever (Steve.Dever@Eng.Sun.Com) +/ +/ Synopsis: (c callable external declarations) +/ extern unsigned char inb(int port); +/ extern unsigned short inw(int port); +/ extern unsigned long inl(int port); +/ extern void outb(int port, unsigned char value); +/ extern void outw(int port, unsigned short value); +/ extern void outl(int port, unsigned long value); +/ + +.file "sunos_inout.s" +.text + +.globl inb +.globl inw +.globl inl +.globl outb +.globl outw +.globl outl + +/ +/ unsigned char inb(int port); +/ +.align 4 +inb: + movl 4(%esp),%edx + subl %eax,%eax + inb (%dx) + ret +.type inb,@function +.size inb,.-inb + +/ +/ unsigned short inw(int port); +/ +.align 4 +inw: + movl 4(%esp),%edx + subl %eax,%eax + inw (%dx) + ret +.type inw,@function +.size inw,.-inw + +/ +/ unsigned long inl(int port); +/ +.align 4 +inl: + movl 4(%esp),%edx + inl (%dx) + ret +.type inl,@function +.size inl,.-inl + +/ +/ void outb(int port, unsigned char value); +/ +.align 4 +outb: + movl 4(%esp),%edx + movl 8(%esp),%eax + outb (%dx) + ret +.type outb,@function +.size outb,.-outb + +/ +/ void outw(int port, unsigned short value); +/ +.align 4 +outw: + movl 4(%esp),%edx + movl 8(%esp),%eax + outw (%dx) + ret +.type outw,@function +.size outw,.-outw + +/ +/ void outl(int port, unsigned long value); +/ +.align 4 +outl: + movl 4(%esp),%edx + movl 8(%esp),%eax + outl (%dx) + ret +.type outl,@function +.size outl,.-outl diff --git a/hw/xfree86/os-support/solaris/sun_io.c b/hw/xfree86/os-support/solaris/sun_io.c new file mode 100644 index 000000000..27996d312 --- /dev/null +++ b/hw/xfree86/os-support/solaris/sun_io.c @@ -0,0 +1,64 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_io.c,v 1.3 2003/02/17 15:12:00 dawes Exp $ */ +/* + * 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 DISCLAIM 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. + * + */ + +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +void +xf86SoundKbdBell(int loudness, int pitch, int duration) +{ + int kbdCmd; + + if (loudness && pitch) + { + kbdCmd = KBD_CMD_BELL; + if (ioctl (xf86Info.kbdFd, KIOCCMD, &kbdCmd) == -1) { + ErrorF("Failed to activate bell\n"); + return; + } + + usleep(xf86Info.bell_duration * loudness * 20); + + kbdCmd = KBD_CMD_NOBELL; + if (ioctl (xf86Info.kbdFd, KIOCCMD, &kbdCmd) == -1) + ErrorF ("Failed to deactivate bell\n"); + } +} + +void +xf86SetKbdLeds(int leds) +{ + if( ioctl(xf86Info.kbdFd, KIOCSLED, &leds) < 0 ) + ErrorF("Failed to set Keyboard LED's\n"); +} + +#include "xf86OSKbd.h" + +Bool +xf86OSKbdPreInit(InputInfoPtr pInfo) +{ + return FALSE; +} diff --git a/hw/xfree86/os-support/solaris/sun_kbd.c b/hw/xfree86/os-support/solaris/sun_kbd.c new file mode 100644 index 000000000..7e4998817 --- /dev/null +++ b/hw/xfree86/os-support/solaris/sun_kbd.c @@ -0,0 +1,112 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_kbd.c,v 1.1 2001/05/28 02:42:31 tsi Exp $ */ +/* + * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany + * Copyright 1993 by David Dawes <dawes@XFree86.org> + * Copyright 1999 by David Holland <davidh@iquest.net) + * + * 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, David Dawes, and David Holland not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. Thomas Roell, David Dawes, and + * David Holland make no representations about the suitability of this software + * for any purpose. It is provided "as is" without express or implied + * warranty. + * + * THOMAS ROELL, DAVID DAWES, AND DAVID HOLLAND DISCLAIM ALL WARRANTIES WITH + * REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS. IN NO EVENT SHALL THOMAS ROELL, DAVID DAWES, OR DAVID HOLLAND + * 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. + */ + +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +static int sun_otranslation = -1; +static int sun_odirect = -1; + +int +xf86GetKbdLeds() +{ + int leds; + + ioctl(xf86Info.kbdFd, KIOCGLED, &leds); + return leds; +} + +void +xf86SetKbdRepeat(char rad) +{ + /* Nothing to do */ +} + +/* + * Save initial keyboard state. This is called at the start of each server + * generation. + */ + +void +xf86KbdInit() +{ + int ktype, klayout; + + if (xf86Info.kbdFd < 0) { + xf86Info.kbdFd = open("/dev/kbd", O_RDWR|O_NONBLOCK); + if(xf86Info.kbdFd < 0) + FatalError("Unable to open keyboard: /dev/kbd\n"); + } + + /* + * None of the followin should ever fail. If it does, something is + * broken (IMO) - DWH 8/21/99 + */ + + if (ioctl(xf86Info.kbdFd, KIOCTYPE, &ktype) < 0) + FatalError("Unable to determine keyboard type: %d\n", errno); + + if (ioctl(xf86Info.kbdFd, KIOCLAYOUT, &klayout) < 0) + FatalError("Unable to determine keyboard layout: %d\n", errno); + + if (ioctl(xf86Info.kbdFd, KIOCGTRANS, &sun_otranslation) < 0) + FatalError("Unable to determine keyboard translation mode\n"); + + if (ioctl(xf86Info.kbdFd, KIOCGDIRECT, &sun_odirect) < 0) + FatalError("Unable to determine keyboard direct setting\n"); +} + +int +xf86KbdOn(void) +{ + int tmp = 1; + + if (ioctl(xf86Info.kbdFd, KIOCSDIRECT, &tmp) == -1) + FatalError("Setting keyboard direct mode on\n"); + + /* Setup translation */ + + tmp = TR_UNTRANS_EVENT; + + if (ioctl(xf86Info.kbdFd, KIOCTRANS, &tmp) == -1) + FatalError("Setting keyboard translation\n"); + + return xf86Info.kbdFd; +} + +int +xf86KbdOff() +{ + if ((sun_otranslation != -1) && + (ioctl(xf86Info.kbdFd, KIOCTRANS, &sun_otranslation) < 0)) + FatalError("Unable to restore keyboard translation mode\n"); + + if ((sun_odirect != 0) && + (ioctl(xf86Info.kbdFd, KIOCSDIRECT, &sun_odirect) < 0 )) + FatalError("Unable to restore keyboard direct setting\n"); + + return xf86Info.kbdFd; +} diff --git a/hw/xfree86/os-support/solaris/sun_kbdEv.c b/hw/xfree86/os-support/solaris/sun_kbdEv.c new file mode 100644 index 000000000..ff4ef3288 --- /dev/null +++ b/hw/xfree86/os-support/solaris/sun_kbdEv.c @@ -0,0 +1,672 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_kbdEv.c,v 1.4 2001/11/08 04:15:33 tsi Exp $ */ +/* + * 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 make 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 DISCLAIM 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. + */ + +/* [JCH-96/01/21] Extended std reverse map to four buttons. */ + +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +#ifdef XINPUT +#include "XI.h" +#include "XIproto.h" +#include "xf86Xinput.h" +#else +#include "inputstr.h" +#endif + +#ifdef XFreeXDGA +#include "dgaproc.h" +#endif + +#include <sys/vuid_event.h> +#include "atKeynames.h" + +#ifdef XKB +extern Bool noXkbExtension; +#endif + +#define XE_POINTER 1 +#define XE_KEYBOARD 2 + +#ifdef XTESTEXT1 + +#define XTestSERVER_SIDE +#include "xtestext1.h" +extern short xtest_mousex; +extern short xtest_mousey; +extern int on_steal_input; +extern Bool XTestStealKeyData(); +extern void XTestStealMotionData(); + +#ifdef XINPUT +#define ENQUEUE(ev, code, direction, dev_type) \ + (ev)->u.u.detail = (code); \ + (ev)->u.u.type = (direction); \ + if (!on_steal_input || \ + XTestStealKeyData((ev)->u.u.detail, (ev)->u.u.type, dev_type, \ + xtest_mousex, xtest_mousey)) \ + xf86eqEnqueue((ev)) +#else +#define ENQUEUE(ev, code, direction, dev_type) \ + (ev)->u.u.detail = (code); \ + (ev)->u.u.type = (direction); \ + if (!on_steal_input || \ + XTestStealKeyData((ev)->u.u.detail, (ev)->u.u.type, dev_type, \ + xtest_mousex, xtest_mousey)) \ + mieqEnqueue((ev)) +#endif + +#else /* ! XTESTEXT1 */ + +#ifdef XINPUT +#define ENQUEUE(ev, code, direction, dev_type) \ + (ev)->u.u.detail = (code); \ + (ev)->u.u.type = (direction); \ + xf86eqEnqueue((ev)) +#else +#define ENQUEUE(ev, code, direction, dev_type) \ + (ev)->u.u.detail = (code); \ + (ev)->u.u.type = (direction); \ + mieqEnqueue((ev)) +#endif + +#endif + +static void startautorepeat(long keycode); +static CARD32 processautorepeat(OsTimerPtr timer, CARD32 now, pointer arg); + +static OsTimerPtr sunTimer = NULL; + +/* Map the Solaris keycodes to the "XFree86" keycodes. */ +/* + * This doesn't seem right. It probably needs to be dependent on a keyboard + * type. + */ +static unsigned char map[256] = { +#if defined(i368) || defined(__i386) || defined(__i386__) + KEY_NOTUSED, /* 0 */ + KEY_Tilde, /* 1 */ + KEY_1, /* 2 */ + KEY_2, /* 3 */ + KEY_3, /* 4 */ + KEY_4, /* 5 */ + KEY_5, /* 6 */ + KEY_6, /* 7 */ + KEY_7, /* 8 */ + KEY_8, /* 9 */ + KEY_9, /* 10 */ + KEY_0, /* 11 */ + KEY_Minus, /* 12 */ + KEY_Equal, /* 13 */ + 0x7D, /*KEY_P_YEN*/ /* 14 */ + KEY_BackSpace, /* 15 */ + KEY_Tab, /* 16 */ + KEY_Q, /* 17 */ + KEY_W, /* 18 */ + KEY_E, /* 19 */ + KEY_R, /* 20 */ + KEY_T, /* 21 */ + KEY_Y, /* 22 */ + KEY_U, /* 23 */ + KEY_I, /* 24 */ + KEY_O, /* 25 */ + KEY_P, /* 26 */ + KEY_LBrace, /* 27 */ + KEY_RBrace, /* 28 */ + KEY_BSlash, /* 29 */ + KEY_CapsLock, /* 30 */ + KEY_A, /* 31 */ + KEY_S, /* 32 */ + KEY_D, /* 33 */ + KEY_F, /* 34 */ + KEY_G, /* 35 */ + KEY_H, /* 36 */ + KEY_J, /* 37 */ + KEY_K, /* 38 */ + KEY_L, /* 39 */ + KEY_SemiColon, /* 40 */ + KEY_Quote, /* 41 */ + KEY_UNKNOWN, /* 42 */ + KEY_Enter, /* 43 */ + KEY_ShiftL, /* 44 */ + KEY_Less, /* 45 */ + KEY_Z, /* 46 */ + KEY_X, /* 47 */ + KEY_C, /* 48 */ + KEY_V, /* 49 */ + KEY_B, /* 50 */ + KEY_N, /* 51 */ + KEY_M, /* 52 */ + KEY_Comma, /* 53 */ + KEY_Period, /* 54 */ + KEY_Slash, /* 55 */ + KEY_BSlash2, /* 56 */ + KEY_ShiftR, /* 57 */ + KEY_LCtrl, /* 58 */ + KEY_LMeta, /* 59 */ + KEY_Alt, /* 60 */ + KEY_Space, /* 61 */ + KEY_AltLang, /* 62 */ + KEY_RMeta, /* 63 */ + KEY_RCtrl, /* 64 */ + KEY_Menu, /* 65 */ + KEY_UNKNOWN, /* 66 */ + KEY_UNKNOWN, /* 67 */ + KEY_UNKNOWN, /* 68 */ + KEY_UNKNOWN, /* 69 */ + KEY_UNKNOWN, /* 70 */ + KEY_UNKNOWN, /* 71 */ + KEY_UNKNOWN, /* 72 */ + KEY_UNKNOWN, /* 73 */ + KEY_UNKNOWN, /* 74 */ + KEY_Insert, /* 75 */ + KEY_Delete, /* 76 */ + KEY_UNKNOWN, /* 77 */ + KEY_UNKNOWN, /* 78 */ + KEY_Left, /* 79 */ + KEY_Home, /* 80 */ + KEY_End, /* 81 */ + KEY_UNKNOWN, /* 82 */ + KEY_Up, /* 83 */ + KEY_Down, /* 84 */ + KEY_PgUp, /* 85 */ + KEY_PgDown, /* 86 */ + KEY_UNKNOWN, /* 87 */ + KEY_UNKNOWN, /* 88 */ + KEY_Right, /* 89 */ + KEY_NumLock, /* 90 */ + KEY_KP_7, /* 91 */ + KEY_KP_4, /* 92 */ + KEY_KP_1, /* 93 */ + KEY_UNKNOWN, /* 94 */ + KEY_KP_Divide, /* 95 */ + KEY_KP_8, /* 96 */ + KEY_KP_5, /* 97 */ + KEY_KP_2, /* 98 */ + KEY_KP_0, /* 99 */ + KEY_KP_Multiply, /* 100 */ + KEY_KP_9, /* 101 */ + KEY_KP_6, /* 102 */ + KEY_KP_3, /* 103 */ + KEY_KP_Decimal, /* 104 */ + KEY_KP_Minus, /* 105 */ + KEY_KP_Plus, /* 106 */ + KEY_UNKNOWN, /* 107 */ + KEY_KP_Enter, /* 108 */ + KEY_UNKNOWN, /* 109 */ + KEY_Escape, /* 110 */ + KEY_UNKNOWN, /* 111 */ + KEY_F1, /* 112 */ + KEY_F2, /* 113 */ + KEY_F3, /* 114 */ + KEY_F4, /* 115 */ + KEY_F5, /* 116 */ + KEY_F6, /* 117 */ + KEY_F7, /* 118 */ + KEY_F8, /* 119 */ + KEY_F9, /* 120 */ + KEY_F10, /* 121 */ + KEY_F11, /* 122 */ + KEY_F12, /* 123 */ + KEY_Print, /* 124 */ + KEY_ScrollLock, /* 125 */ + KEY_Pause, /* 126 */ + KEY_UNKNOWN, /* 127 */ + KEY_UNKNOWN, /* 128 */ + KEY_UNKNOWN, /* 129 */ + KEY_UNKNOWN, /* 130 */ + KEY_NFER, /* 131 */ + KEY_XFER, /* 132 */ + KEY_HKTG, /* 133 */ + KEY_UNKNOWN, /* 134 */ +#elif defined(sparc) || defined(__sparc__) + KEY_UNKNOWN, /* 0x00 */ + KEY_UNKNOWN, /* 0x01 */ + KEY_UNKNOWN, /* 0x02 */ + KEY_UNKNOWN, /* 0x03 */ + KEY_UNKNOWN, /* 0x04 */ + KEY_F1, /* 0x05 */ + KEY_F2, /* 0x06 */ + KEY_F10, /* 0x07 */ + KEY_F3, /* 0x08 */ + KEY_F11, /* 0x09 */ + KEY_F4, /* 0x0A */ + KEY_F12, /* 0x0B */ + KEY_F5, /* 0x0C */ + KEY_UNKNOWN, /* 0x0D */ + KEY_F6, /* 0x0E */ + KEY_UNKNOWN, /* 0x0F */ + KEY_F7, /* 0x10 */ + KEY_F8, /* 0x11 */ + KEY_F9, /* 0x12 */ + KEY_Alt, /* 0x13 */ + KEY_Up, /* 0x14 */ + KEY_Pause, /* 0x15 */ + KEY_SysReqest, /* 0x16 */ + KEY_ScrollLock, /* 0x17 */ + KEY_Left, /* 0x18 */ + KEY_UNKNOWN, /* 0x19 */ + KEY_UNKNOWN, /* 0x1A */ + KEY_Down, /* 0x1B */ + KEY_Right, /* 0x1C */ + KEY_Escape, /* 0x1D */ + KEY_1, /* 0x1E */ + KEY_2, /* 0x1F */ + KEY_3, /* 0x20 */ + KEY_4, /* 0x21 */ + KEY_5, /* 0x22 */ + KEY_6, /* 0x23 */ + KEY_7, /* 0x24 */ + KEY_8, /* 0x25 */ + KEY_9, /* 0x26 */ + KEY_0, /* 0x27 */ + KEY_Minus, /* 0x28 */ + KEY_Equal, /* 0x29 */ + KEY_Tilde, /* 0x2A */ + KEY_BackSpace, /* 0x2B */ + KEY_Insert, /* 0x2C */ + KEY_UNKNOWN, /* 0x2D */ + KEY_KP_Divide, /* 0x2E */ + KEY_KP_Multiply, /* 0x2F */ + KEY_UNKNOWN, /* 0x30 */ + KEY_UNKNOWN, /* 0x31 */ + KEY_KP_Decimal, /* 0x32 */ + KEY_UNKNOWN, /* 0x33 */ + KEY_Home, /* 0x34 */ + KEY_Tab, /* 0x35 */ + KEY_Q, /* 0x36 */ + KEY_W, /* 0x37 */ + KEY_E, /* 0x38 */ + KEY_R, /* 0x39 */ + KEY_T, /* 0x3A */ + KEY_Y, /* 0x3B */ + KEY_U, /* 0x3C */ + KEY_I, /* 0x3D */ + KEY_O, /* 0x3E */ + KEY_P, /* 0x3F */ + KEY_LBrace, /* 0x40 */ + KEY_RBrace, /* 0x41 */ + KEY_Delete, /* 0x42 */ + KEY_UNKNOWN, /* 0x43 */ + KEY_KP_7, /* 0x44 */ + KEY_KP_8, /* 0x45 */ + KEY_KP_9, /* 0x46 */ + KEY_KP_Minus, /* 0x47 */ + KEY_UNKNOWN, /* 0x48 */ + KEY_UNKNOWN, /* 0x49 */ + KEY_End, /* 0x4A */ + KEY_UNKNOWN, /* 0x4B */ + KEY_LCtrl, /* 0x4C */ + KEY_A, /* 0x4D */ + KEY_S, /* 0x4E */ + KEY_D, /* 0x4F */ + KEY_F, /* 0x50 */ + KEY_G, /* 0x51 */ + KEY_H, /* 0x52 */ + KEY_J, /* 0x53 */ + KEY_K, /* 0x54 */ + KEY_L, /* 0x55 */ + KEY_SemiColon, /* 0x56 */ + KEY_Quote, /* 0x57 */ + KEY_BSlash, /* 0x58 */ + KEY_Enter, /* 0x59 */ + KEY_KP_Enter, /* 0x5A */ + KEY_KP_4, /* 0x5B */ + KEY_KP_5, /* 0x5C */ + KEY_KP_6, /* 0x5D */ + KEY_KP_0, /* 0x5E */ + KEY_UNKNOWN, /* 0x5F */ + KEY_PgUp, /* 0x60 */ + KEY_UNKNOWN, /* 0x61 */ + KEY_NumLock, /* 0x62 */ + KEY_ShiftL, /* 0x63 */ + KEY_Z, /* 0x64 */ + KEY_X, /* 0x65 */ + KEY_C, /* 0x66 */ + KEY_V, /* 0x67 */ + KEY_B, /* 0x68 */ + KEY_N, /* 0x69 */ + KEY_M, /* 0x6A */ + KEY_Comma, /* 0x6B */ + KEY_Period, /* 0x6C */ + KEY_Slash, /* 0x6D */ + KEY_ShiftR, /* 0x6E */ + KEY_UNKNOWN, /* 0x6F */ + KEY_KP_1, /* 0x70 */ + KEY_KP_2, /* 0x71 */ + KEY_KP_3, /* 0x72 */ + KEY_UNKNOWN, /* 0x73 */ + KEY_UNKNOWN, /* 0x74 */ + KEY_UNKNOWN, /* 0x75 */ + KEY_UNKNOWN, /* 0x76 */ + KEY_CapsLock, /* 0x77 */ + KEY_LMeta, /* 0x78 */ + KEY_Space, /* 0x79 */ + KEY_RMeta, /* 0x7A */ + KEY_PgDown, /* 0x7B */ + KEY_UNKNOWN, /* 0x7C */ + KEY_KP_Plus, /* 0x7D */ + KEY_UNKNOWN, /* 0x7E */ + KEY_UNKNOWN, /* 0x7F */ +#endif + /* The rest default to KEY_UNKNOWN */ +}; + +/* + * sunPostKbdEvent -- + * Translate the raw hardware Firm_event into an XEvent, and tell DIX + * about it. KeyCode preprocessing and so on is done ... + * + * Most of the Solaris stuff has whacked Panix/PC98 support in the + * interests of simplicity - DWH 8/30/99 + */ + +static void +sunPostKbdEvent(Firm_event *event) +{ + Bool down; + KeyClassRec *keyc = ((DeviceIntPtr)xf86Info.pKeyboard)->key; + Bool updateLeds = FALSE; + xEvent kevent; + KeySym *keysym; + int keycode; + static int lockkeys = 0; + + /* Give down a value */ + if (event->value == VKEY_DOWN) + down = TRUE; + else + down = FALSE; + + /* + * and now get some special keysequences + */ + + keycode = map[event->id]; + + if ((ModifierDown(ControlMask | AltMask)) || + (ModifierDown(ControlMask | AltLangMask))) + { + switch (keycode) { + /* + * The idea here is to pass the scancode down to a list of registered + * routines. There should be some standard conventions for processing + * certain keys. + */ + + case KEY_BackSpace: + if (!xf86Info.dontZap) { + DGAShutdown(); + GiveUp(0); + } + break; + + /* Check grabs */ + case KEY_KP_Divide: + if (!xf86Info.grabInfo.disabled && + xf86Info.grabInfo.allowDeactivate) { + if (inputInfo.pointer && inputInfo.pointer->grab != NULL && + inputInfo.pointer->DeactivateGrab) + (*inputInfo.pointer->DeactivateGrab)(inputInfo.pointer); + if (inputInfo.keyboard && inputInfo.keyboard->grab != NULL && + inputInfo.keyboard->DeactivateGrab) + (*inputInfo.keyboard->DeactivateGrab)(inputInfo.keyboard); + } + break; + + case KEY_KP_Multiply: + if (!xf86Info.grabInfo.disabled && + xf86Info.grabInfo.allowClosedown) { + ClientPtr pointer, keyboard, server; + + pointer = keyboard = server = NULL; + if (inputInfo.pointer && inputInfo.pointer->grab != NULL) + pointer = + clients[CLIENT_ID(inputInfo.pointer->grab->resource)]; + + if (inputInfo.keyboard && inputInfo.keyboard->grab != NULL) { + keyboard = + clients[CLIENT_ID(inputInfo.keyboard->grab->resource)]; + if (keyboard == pointer) + keyboard = NULL; + } + + if ((xf86Info.grabInfo.server.grabstate == SERVER_GRABBED) && + (((server = xf86Info.grabInfo.server.client) == pointer) || + (server == keyboard))) + server = NULL; + + if (pointer) + CloseDownClient(pointer); + if (keyboard) + CloseDownClient(keyboard); + if (server) + CloseDownClient(server); + } + break; + + case KEY_KP_Minus: /* Keypad - */ + if (!xf86Info.dontZoom) { + if (down) + xf86ZoomViewport(xf86Info.currentScreen, -1); + return; + } + break; + + case KEY_KP_Plus: /* Keypad + */ + if (!xf86Info.dontZoom) { + if (down) + xf86ZoomViewport(xf86Info.currentScreen, 1); + return; + } + break; + } + } + + /* + * Now map the scancodes to real X-keycodes ... + */ + if (keycode == KEY_NOTUSED) { + xf86MsgVerb(X_INFO, 0, + "raw code %d mapped to KEY_NOTUSED -- please report\n", event->id); + return; + } + if (keycode == KEY_UNKNOWN) { + xf86MsgVerb(X_INFO, 0, + "raw code %d mapped to KEY_UNKNOWN -- please report\n", event->id); + return; + } + keycode += MIN_KEYCODE; + keysym = keyc->curKeySyms.map + + (keyc->curKeySyms.mapWidth * + (keycode - keyc->curKeySyms.minKeyCode)); + +#ifdef XKB + if (noXkbExtension) +#endif + { + /* + * Toggle lock keys. + */ +#define CAPSFLAG 0x01 +#define NUMFLAG 0x02 +#define SCROLLFLAG 0x04 +#define MODEFLAG 0x08 + + if (down) { + /* + * Handle the KeyPresses of the lock keys. + */ + + switch (keysym[0]) { + + case XK_Caps_Lock: + if (lockkeys & CAPSFLAG) { + lockkeys &= ~CAPSFLAG; + return; + } + lockkeys |= CAPSFLAG; + updateLeds = TRUE; + xf86Info.capsLock = down; + break; + + case XK_Num_Lock: + if (lockkeys & NUMFLAG) { + lockkeys &= ~NUMFLAG; + return; + } + lockkeys |= NUMFLAG; + updateLeds = TRUE; + xf86Info.numLock = down; + break; + + case XK_Scroll_Lock: + if (lockkeys & SCROLLFLAG) { + lockkeys &= ~SCROLLFLAG; + return; + } + lockkeys |= SCROLLFLAG; + updateLeds = TRUE; + xf86Info.scrollLock = down; + break; + } + } else { + /* + * Handle the releases of the lock keys. + */ + + switch (keysym[0]) { + + case XK_Caps_Lock: + if (lockkeys & CAPSFLAG) + return; + updateLeds = TRUE; + xf86Info.capsLock = down; + break; + + case XK_Num_Lock: + if (lockkeys & NUMFLAG) + return; + updateLeds = TRUE; + xf86Info.numLock = down; + break; + + case XK_Scroll_Lock: + if (lockkeys & SCROLLFLAG) + return; + updateLeds = TRUE; + xf86Info.scrollLock = down; + break; + } + } + + if (updateLeds) + xf86KbdLeds(); + + /* + * If this keycode is not a modifier key, and its down initiate the + * autorepeate sequence. (Only necessary if not using XKB). + * + * If its not down, then reset the timer. + */ + if (!keyc->modifierMap[keycode]) { + if (down) { + startautorepeat(keycode); + } else { + TimerFree(sunTimer); + sunTimer = NULL; + } + } + } + + xf86Info.lastEventTime = + kevent.u.keyButtonPointer.time = + GetTimeInMillis(); + + /* + * And now send these prefixes ... + * NOTE: There cannot be multiple Mode_Switch keys !!!! + */ + + ENQUEUE(&kevent, keycode, (down ? KeyPress : KeyRelease), XE_KEYBOARD); +} + +/* + * Lets try reading more than one keyboard event at a time in the hopes that + * this will be slightly more efficient. Or we could just try the MicroSoft + * method, and forget about efficiency. :-) + */ +void +xf86KbdEvents() +{ + Firm_event event[64]; + int nBytes, i; + + /* I certainly hope its not possible to read partial events */ + + if ((nBytes = read(xf86Info.kbdFd, (char *)event, sizeof(event))) > 0) + { + for (i = 0; i < (nBytes / sizeof(Firm_event)); i++) + sunPostKbdEvent(&event[i]); + } +} + +/* + * Autorepeat stuff + */ + +void +startautorepeat(long keycode) +{ + sunTimer = TimerSet(sunTimer, /* Timer */ + 0, /* Flags */ + xf86Info.kbdDelay, /* millis */ + processautorepeat, /* callback */ + (pointer) keycode); /* arg for timer */ +} + +CARD32 +processautorepeat(OsTimerPtr timer, CARD32 now, pointer arg) +{ + xEvent kevent; + int keycode; + + keycode = (long)arg; + + xf86Info.lastEventTime = + kevent.u.keyButtonPointer.time = + GetTimeInMillis(); + + /* + * Repeat a key by faking a KeyRelease, and a KeyPress event in rapid + * succession + */ + + ENQUEUE(&kevent, keycode, KeyRelease, XE_KEYBOARD); + ENQUEUE(&kevent, keycode, KeyPress, XE_KEYBOARD); + + /* And return the appropriate value so we get rescheduled */ + return xf86Info.kbdRate; +} diff --git a/hw/xfree86/os-support/solaris/sun_mouse.c b/hw/xfree86/os-support/solaris/sun_mouse.c new file mode 100644 index 000000000..2e9cee2b1 --- /dev/null +++ b/hw/xfree86/os-support/solaris/sun_mouse.c @@ -0,0 +1,322 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_mouse.c,v 1.4 2002/01/25 21:56:21 tsi Exp $ */ +/* + * Copyright 1999-2001 The XFree86 Project, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * XFREE86 PROJECT BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * Except as contained in this notice, the name of the XFree86 Project shall + * not be used in advertising or otherwise to promote the sale, use or other + * dealings in this Software without prior written authorization from the + * XFree86 Project. + */ + +#include "xf86.h" +#include "xf86_OSlib.h" +#include "xf86OSmouse.h" + +#if defined(__SOL8__) || !defined(i386) + +#include "xisb.h" +#include "mipointer.h" +#include <sys/vuid_event.h> + +/* Names of protocols that are handled internally here. */ + +static const char *internalNames[] = { + "VUID", + NULL +}; + +typedef struct _VuidMseRec { + Firm_event event; + unsigned char *buffer; +} VuidMseRec, *VuidMsePtr; + + +static int vuidMouseProc(DeviceIntPtr pPointer, int what); +static void vuidReadInput(InputInfoPtr pInfo); + +/* This function is called when the protocol is "VUID". */ +static Bool +vuidPreInit(InputInfoPtr pInfo, const char *protocol, int flags) +{ + MouseDevPtr pMse = pInfo->private; + VuidMsePtr pVuidMse; + + pVuidMse = xalloc(sizeof(VuidMseRec)); + if (pVuidMse == NULL) { + xf86Msg(X_ERROR, "%s: cannot allocate VuidMouseRec\n", pInfo->name); + xfree(pMse); + return FALSE; + } + + pMse->protocol = protocol; + xf86Msg(X_CONFIG, "%s: Protocol: %s\n", pInfo->name, protocol); + + /* Collect the options, and process the common options. */ + xf86CollectInputOptions(pInfo, NULL, NULL); + xf86ProcessCommonOptions(pInfo, pInfo->options); + + /* Check if the device can be opened. */ + pInfo->fd = xf86OpenSerial(pInfo->options); + if (pInfo->fd == -1) { + if (xf86GetAllowMouseOpenFail()) + xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name); + else { + xf86Msg(X_ERROR, "%s: cannot open input device\n", pInfo->name); + xfree(pVuidMse); + xfree(pMse); + return FALSE; + } + } + pVuidMse->buffer = (unsigned char *)&pVuidMse->event; + xf86CloseSerial(pInfo->fd); + pInfo->fd = -1; + + /* Private structure */ + pMse->mousePriv = pVuidMse; + + /* Process common mouse options (like Emulate3Buttons, etc). */ + pMse->CommonOptions(pInfo); + + /* Setup the local procs. */ + pInfo->device_control = vuidMouseProc; + pInfo->read_input = vuidReadInput; + + pInfo->flags |= XI86_CONFIGURED; + return TRUE; +} + +static void +vuidReadInput(InputInfoPtr pInfo) +{ + MouseDevPtr pMse; + VuidMsePtr pVuidMse; + int buttons; + int dx = 0, dy = 0, dz = 0, dw = 0; + unsigned int n; + int c; + unsigned char *pBuf; + + pMse = pInfo->private; + pVuidMse = pMse->mousePriv; + buttons = pMse->lastButtons; + XisbBlockDuration(pMse->buffer, -1); + pBuf = pVuidMse->buffer; + n = 0; + + do { + while (n < sizeof(Firm_event) && (c = XisbRead(pMse->buffer)) >= 0) { + pBuf[n++] = (unsigned char)c; + } + + if (n == 0) + return; + + if (n != sizeof(Firm_event)) { + xf86Msg(X_WARNING, "%s: incomplete packet, size %d\n", + pInfo->name, n); + } + + if (pVuidMse->event.id >= BUT_FIRST && pVuidMse->event.id <= BUT_LAST) { + /* button */ + int butnum = pVuidMse->event.id - BUT_FIRST; + if (butnum < 3) + butnum = 2 - butnum; + if (!pVuidMse->event.value) + buttons &= ~(1 << butnum); + else + buttons |= (1 << butnum); + } else if (pVuidMse->event.id >= VLOC_FIRST && + pVuidMse->event.id <= VLOC_LAST) { + /* axis */ + int delta = pVuidMse->event.value; + switch(pVuidMse->event.id) { + case LOC_X_DELTA: + dx += delta; + break; + case LOC_Y_DELTA: + dy -= delta; + break; + } + } + + n = 0; + if ((c = XisbRead(pMse->buffer)) >= 0) { + /* Another packet. Handle it right away. */ + pBuf[n++] = c; + } + } while (n != 0); + + pMse->PostEvent(pInfo, buttons, dx, dy, dz, dw); + return; +} + +#define NUMEVENTS 64 + +static int +vuidMouseProc(DeviceIntPtr pPointer, int what) +{ + InputInfoPtr pInfo; + MouseDevPtr pMse; + VuidMsePtr pVuidMse; + unsigned char map[MSE_MAXBUTTONS + 1]; + int nbuttons; + + pInfo = pPointer->public.devicePrivate; + pMse = pInfo->private; + pMse->device = pPointer; + pVuidMse = pMse->mousePriv; + + switch (what) { + case DEVICE_INIT: + pPointer->public.on = FALSE; + + for (nbuttons = 0; nbuttons < MSE_MAXBUTTONS; ++nbuttons) + map[nbuttons + 1] = nbuttons + 1; + + InitPointerDeviceStruct((DevicePtr)pPointer, + map, + min(pMse->buttons, MSE_MAXBUTTONS), + miPointerGetMotionEvents, + pMse->Ctrl, + miPointerGetMotionBufferSize()); + + /* X valuator */ + xf86InitValuatorAxisStruct(pPointer, 0, 0, -1, 1, 0, 1); + xf86InitValuatorDefaults(pPointer, 0); + /* Y valuator */ + xf86InitValuatorAxisStruct(pPointer, 1, 0, -1, 1, 0, 1); + xf86InitValuatorDefaults(pPointer, 1); + xf86MotionHistoryAllocate(pInfo); + break; + + case DEVICE_ON: + pInfo->fd = xf86OpenSerial(pInfo->options); + if (pInfo->fd == -1) + xf86Msg(X_WARNING, "%s: cannot open input device\n", pInfo->name); + else { + pMse->buffer = XisbNew(pInfo->fd, + NUMEVENTS * sizeof(Firm_event)); + if (!pMse->buffer) { + xfree(pMse); + xf86CloseSerial(pInfo->fd); + pInfo->fd = -1; + } else { + int fmt = VUID_FIRM_EVENT; + ioctl(pInfo->fd, VUIDSFORMAT, &fmt); + xf86FlushInput(pInfo->fd); + AddEnabledDevice(pInfo->fd); + } + } + pMse->lastButtons = 0; + pMse->emulateState = 0; + pPointer->public.on = TRUE; + break; + + case DEVICE_OFF: + case DEVICE_CLOSE: + if (pInfo->fd != -1) { + RemoveEnabledDevice(pInfo->fd); + if (pMse->buffer) { + XisbFree(pMse->buffer); + pMse->buffer = NULL; + } + xf86CloseSerial(pInfo->fd); + pInfo->fd = -1; + } + pPointer->public.on = FALSE; + usleep(300000); + break; + } + return Success; +} + +static Bool +sunMousePreInit(InputInfoPtr pInfo, const char *protocol, int flags) +{ + /* The protocol is guaranteed to be one of the internalNames[] */ + if (xf86NameCmp(protocol, "VUID") == 0) { + return vuidPreInit(pInfo, protocol, flags); + } + return TRUE; +} + +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; +} + +static const char * +DefaultProtocol(void) +{ + return "VUID"; +} + +static const char * +SetupAuto(InputInfoPtr pInfo, int *protoPara) +{ + return DefaultProtocol(); +} + +#else /* __SOL8__ || !i386 */ + +#undef MSE_MISC +#define MSE_MISC 0 + +#endif /* !__SOL8__ && i386 */ + +static int +SupportedInterfaces(void) +{ + /* XXX This needs to be checked. */ + return MSE_SERIAL | MSE_BUS | MSE_PS2 | MSE_AUTO | MSE_XPS2 | MSE_MISC; +} + +OSMouseInfoPtr +xf86OSMouseInit(int flags) +{ + OSMouseInfoPtr p; + + p = xcalloc(sizeof(OSMouseInfoRec), 1); + if (!p) + return NULL; + p->SupportedInterfaces = SupportedInterfaces; +#if defined(__SOL8__) || !defined(i386) + p->BuiltinNames = BuiltinNames; + p->CheckProtocol = CheckProtocol; + p->PreInit = sunMousePreInit; + p->DefaultProtocol = DefaultProtocol; + p->SetupAuto = SetupAuto; +#endif + return p; +} + diff --git a/hw/xfree86/os-support/solaris/sun_vid.c b/hw/xfree86/os-support/solaris/sun_vid.c new file mode 100644 index 000000000..2f4b84e99 --- /dev/null +++ b/hw/xfree86/os-support/solaris/sun_vid.c @@ -0,0 +1,229 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sunos/sun_vid.c,v 1.3 2002/10/03 02:04:19 tsi Exp $ */ +/* + * 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 the copyright holders not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. The copyright holders make no representations + * about the suitability of this software for any purpose. It is provided "as + * is" without express or implied warranty. + * + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT + * SHALL THE COPYRIGHT HOLDERS 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 i386 +#define _NEED_SYSI86 +#endif +#include "xf86.h" +#include "xf86Priv.h" +#include "xf86_OSlib.h" + +#ifndef MAP_FAILED +#define MAP_FAILED ((void *)-1) +#endif + +/***************************************************************************/ +/* Video Memory Mapping section */ +/***************************************************************************/ + +char *apertureDevName = NULL; + +Bool +xf86LinearVidMem(void) +{ + int mmapFd; + + if (apertureDevName) + return TRUE; + + apertureDevName = "/dev/xsvc"; + if ((mmapFd = open(apertureDevName, O_RDWR)) < 0) + { + apertureDevName = "/dev/fbs/aperture"; + if((mmapFd = open(apertureDevName, O_RDWR)) < 0) + { + xf86MsgVerb(X_WARNING, 0, + "xf86LinearVidMem: failed to open %s (%s)\n", + apertureDevName, strerror(errno)); + xf86MsgVerb(X_WARNING, 0, + "xf86LinearVidMem: either /dev/fbs/aperture or /dev/xsvc" + " device driver required\n"); + xf86MsgVerb(X_WARNING, 0, + "xf86LinearVidMem: linear memory access disabled\n"); + apertureDevName = NULL; + return FALSE; + } + } + close(mmapFd); + return TRUE; +} + +pointer +xf86MapVidMem(int ScreenNum, int Flags, unsigned long Base, unsigned long Size) +{ + pointer base; + int fd; + char vtname[20]; + + /* + * Solaris 2.1 x86 SVR4 (10/27/93) + * The server must treat the virtual terminal device file as the + * standard SVR4 /dev/pmem. + * + * Using the /dev/vtXX device as /dev/pmem only works for the + * A0000-FFFFF region - If we wish you mmap the linear aperture + * it requires a device driver. + * + * So what we'll do is use /dev/vtXX for the A0000-FFFFF stuff, and + * try to use the /dev/fbs/aperture or /dev/xsvc driver if the server + * tries to mmap anything > FFFFF. Its very very unlikely that the + * server will try to mmap anything below FFFFF that can't be handled + * by /dev/vtXX. + * + * DWH - 2/23/94 + * DWH - 1/31/99 (Gee has it really been 5 years?) + * + * Solaris 2.8 7/26/99 + * Use /dev/xsvc for everything + * + * DWH - 7/26/99 - Solaris8/dev/xsvc changes + * + * TSI - 2001.09 - SPARC changes + */ + +#if defined(i386) && !defined(__SOL8__) + if(Base < 0xFFFFF) + sprintf(vtname, "/dev/vt%02d", xf86Info.vtno); + else +#endif + { + if (!xf86LinearVidMem()) + FatalError("xf86MapVidMem: no aperture device\n"); + + strcpy(vtname, apertureDevName); + } + + fd = open(vtname, (Flags & VIDMEM_READONLY) ? O_RDONLY : O_RDWR); + if (fd < 0) + FatalError("xf86MapVidMem: failed to open %s (%s)\n", + vtname, strerror(errno)); + + base = mmap(NULL, Size, + (Flags & VIDMEM_READONLY) ? + PROT_READ : (PROT_READ | PROT_WRITE), + MAP_SHARED, fd, (off_t)Base); + close(fd); + if (base == MAP_FAILED) + FatalError("xf86MapVidMem: mmap failure: %s\n", + strerror(errno)); + + return(base); +} + +/* ARGSUSED */ +void +xf86UnMapVidMem(int ScreenNum, pointer Base, unsigned long Size) +{ + munmap(Base, Size); +} + +/***************************************************************************/ +/* I/O Permissions section */ +/***************************************************************************/ + +#ifdef i386 +static Bool ExtendedEnabled = FALSE; +#endif + +void +xf86EnableIO(void) +{ +#ifdef i386 + if (ExtendedEnabled) + return; + + if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0) + FatalError("xf86EnableIOPorts: Failed to set IOPL for I/O\n"); + + ExtendedEnabled = TRUE; +#endif /* i386 */ +} + +void +xf86DisableIO(void) +{ +#ifdef i386 + if(!ExtendedEnabled) + return; + + sysi86(SI86V86, V86SC_IOPL, 0); + + ExtendedEnabled = FALSE; +#endif /* i386 */ +} + + +/***************************************************************************/ +/* Interrupt Handling section */ +/***************************************************************************/ + +Bool xf86DisableInterrupts(void) +{ +#ifdef i386 + if (!ExtendedEnabled && (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0)) + return FALSE; + +#ifdef __GNUC__ + __asm__ __volatile__("cli"); +#else + asm("cli"); +#endif /* __GNUC__ */ + + if (!ExtendedEnabled) + sysi86(SI86V86, V86SC_IOPL, 0); +#endif /* i386 */ + + return TRUE; +} + +void xf86EnableInterrupts(void) +{ +#ifdef i386 + if (!ExtendedEnabled && (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0)) + return; + +#ifdef __GNUC__ + __asm__ __volatile__("sti"); +#else + asm("sti"); +#endif /* __GNUC__ */ + + if (!ExtendedEnabled) + sysi86(SI86V86, V86SC_IOPL, 0); +#endif /* i386 */ +} + +void +xf86MapReadSideEffects(int ScreenNum, int Flags, pointer Base, + unsigned long Size) +{ +} + +Bool +xf86CheckMTRR(int ScreenNum) +{ + return FALSE; +} + diff --git a/hw/xfree86/os-support/sysv/sysv_mouse.c b/hw/xfree86/os-support/sysv/sysv_mouse.c new file mode 100644 index 000000000..cfba52c2c --- /dev/null +++ b/hw/xfree86/os-support/sysv/sysv_mouse.c @@ -0,0 +1,60 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sysv/sysv_mouse.c,v 1.3 1999/09/04 13:04:49 dawes Exp $ */ + +/* + * Copyright 1999 by The XFree86 Project, Inc. + */ + +#include "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; +} + +#ifndef ISC +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; +} +#endif + +OSMouseInfoPtr +xf86OSMouseInit(int flags) +{ + OSMouseInfoPtr p; + + p = xcalloc(sizeof(OSMouseInfoRec), 1); + if (!p) + return NULL; + p->SupportedInterfaces = SupportedInterfaces; +#ifndef ISC + p->BuiltinNames = BuiltinNames; + p->CheckProtocol = CheckProtocol; + p->PreInit = XqueueMousePreInit; +#endif + return p; +} + diff --git a/hw/xfree86/os-support/sysv/xqueue.h b/hw/xfree86/os-support/sysv/xqueue.h new file mode 100644 index 000000000..2085a3e70 --- /dev/null +++ b/hw/xfree86/os-support/sysv/xqueue.h @@ -0,0 +1,8 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/sysv/xqueue.h,v 1.1 1999/05/22 08:40:18 dawes Exp $ */ + +#ifndef _XF86_XQUEUE_H_ +#define _XF86_XQUEUE_H_ + +Bool XqueueMousePreInit(InputInfoPtr pInfo, const char *protocol, int flags); + +#endif diff --git a/hw/xfree86/os-support/xf86OSKbd.h b/hw/xfree86/os-support/xf86OSKbd.h new file mode 100644 index 000000000..e63d7759c --- /dev/null +++ b/hw/xfree86/os-support/xf86OSKbd.h @@ -0,0 +1,92 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86OSKbd.h,v 1.3 2003/02/17 15:11:55 dawes Exp $ */ + +/* + * Copyright (c) 2002 by The XFree86 Project, Inc. + * Author: Ivan Pascal. + */ + +#include "xf86Xinput.h" + +Bool ATScancode(InputInfoPtr pInfo, int *scanCode); + +/* Public interface to OS-specific keyboard support. */ + +typedef int (*KbdInitProc)(InputInfoPtr pInfo, int what); +typedef int (*KbdOnProc)(InputInfoPtr pInfo, int what); +typedef int (*KbdOffProc)(InputInfoPtr pInfo, int what); +typedef void (*BellProc)(InputInfoPtr pInfo, + int loudness, int pitch, int duration); +typedef void (*SetLedsProc)(InputInfoPtr pInfo, int leds); +typedef int (*GetLedsProc)(InputInfoPtr pInfo); +typedef void (*SetKbdRepeatProc)(InputInfoPtr pInfo, char rad); +typedef void (*KbdGetMappingProc)(InputInfoPtr pInfo, + KeySymsPtr pKeySyms, CARD8* pModMap); +typedef int (*GetSpecialKeyProc)(InputInfoPtr pInfo, int scanCode); +typedef Bool (*SpecialKeyProc)(InputInfoPtr pInfo, + int key, Bool down, int modifiers); +typedef int (*RemapScanCodeProc)(InputInfoPtr pInfo, int *scanCode); +typedef Bool (*OpenKeyboardProc)(InputInfoPtr pInfo); +typedef void (*PostEventProc)(InputInfoPtr pInfo, + unsigned int key, Bool down); +typedef struct { + int begin; + int end; + unsigned char *map; +} TransMapRec, *TransMapPtr; + +typedef struct { + KbdInitProc KbdInit; + KbdOnProc KbdOn; + KbdOffProc KbdOff; + BellProc Bell; + SetLedsProc SetLeds; + GetLedsProc GetLeds; + SetKbdRepeatProc SetKbdRepeat; + KbdGetMappingProc KbdGetMapping; + RemapScanCodeProc RemapScanCode; + GetSpecialKeyProc GetSpecialKey; + SpecialKeyProc SpecialKey; + + OpenKeyboardProc OpenKeyboard; + PostEventProc PostEvent; + + int rate; + int delay; + int bell_pitch; + int bell_duration; + Bool autoRepeat; + unsigned long leds; + unsigned long xledsMask; + unsigned long keyLeds; + int scanPrefix; + Bool vtSwitchSupported; + Bool CustomKeycodes; + Bool noXkb; + Bool isConsole; + TransMapPtr scancodeMap; + TransMapPtr specialMap; + + /* os specific */ + pointer private; + int kbdType; + int consType; + int wsKbdType; + Bool sunKbd; + Bool Panix106; + +} KbdDevRec, *KbdDevPtr; + +typedef enum { + PROT_STD, + PROT_XQUEUE, + PROT_WSCONS, + PROT_USB, + PROT_UNKNOWN +} KbdProtocolId; + +typedef struct { + const char *name; + KbdProtocolId id; +} KbdProtocolRec; + +Bool xf86OSKbdPreInit(InputInfoPtr pInfo); diff --git a/hw/xfree86/os-support/xf86OSmouse.h b/hw/xfree86/os-support/xf86OSmouse.h new file mode 100644 index 000000000..a4486b987 --- /dev/null +++ b/hw/xfree86/os-support/xf86OSmouse.h @@ -0,0 +1,181 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86OSmouse.h,v 1.20 2002/12/17 20:55:23 dawes Exp $ */ + +/* + * Copyright (c) 1997-1999 by The XFree86 Project, Inc. + */ + +/* Public interface to OS-specific mouse support. */ + +#ifndef _XF86OSMOUSE_H_ +#define _XF86OSMOUSE_H_ + +#include "xf86Xinput.h" + +/* Mouse interface classes */ +#define MSE_NONE 0x00 +#define MSE_SERIAL 0x01 /* serial port */ +#define MSE_BUS 0x02 /* old bus mouse */ +#define MSE_PS2 0x04 /* standard read-only PS/2 */ +#define MSE_XPS2 0x08 /* extended PS/2 */ +#define MSE_AUTO 0x10 /* auto-detect (PnP) */ +#define MSE_MISC 0x20 /* The OS layer will identify the + * specific protocol names that are + * supported for this class. */ + +struct _MouseDevRec; + +typedef int (*GetInterfaceTypesProc)(void); +typedef const char **(*BuiltinNamesProc)(void); +typedef Bool (*CheckProtocolProc)(const char *protocol); +typedef Bool (*BuiltinPreInitProc)(InputInfoPtr pInfo, const char *protocol, + int flags); +typedef const char *(*DefaultProtocolProc)(void); +typedef const char *(*SetupAutoProc)(InputInfoPtr pInfo, int *protoPara); +typedef void (*SetResProc)(InputInfoPtr pInfo, const char* protocol, int rate, + int res); +typedef void (*checkMovementsProc)(InputInfoPtr,int, int); +typedef void (*autoProbeProc)(InputInfoPtr, Bool, Bool); +typedef Bool (*collectDataProc)(struct _MouseDevRec *, unsigned char); +typedef Bool (*dataGoodProc)(struct _MouseDevRec *); + +/* + * OSMouseInfoRec is used to pass information from the OSMouse layer to the + * OS-independent mouse driver. + */ +typedef struct { + GetInterfaceTypesProc SupportedInterfaces; + BuiltinNamesProc BuiltinNames; + CheckProtocolProc CheckProtocol; + BuiltinPreInitProc PreInit; + DefaultProtocolProc DefaultProtocol; + SetupAutoProc SetupAuto; + SetResProc SetPS2Res; + SetResProc SetBMRes; + SetResProc SetMiscRes; +} OSMouseInfoRec, *OSMouseInfoPtr; + +/* + * SupportedInterfaces: Returns the mouse interface types that the OS support. + * If MSE_MISC is returned, then the BuiltinNames and + * CheckProtocol should be set. + * + * BuiltinNames: Returns the names of the protocols that are fully handled + * in the OS-specific code. These are names that don't appear + * directly in the main "mouse" driver. + * + * CheckProtocol: Checks if the protocol name given is supported by the + * OS. It should return TRUE for both "builtin" protocols and + * protocols of type MSE_MISC that are supported by the OS. + * + * PreInit: The PreInit function for protocols that are builtin. This + * function is passed the protocol name. + * + * DefaultProtocol: Returns the name of a default protocol that should be used + * for the OS when none has been supplied in the config file. + * This should only be set when there is a reasonable default. + * + * SetupAuto: This function can be used to do OS-specific protocol + * auto-detection. It returns the name of the detected protocol, + * or NULL when detection fails. It may also adjust one or more + * of the "protoPara" values for the detected protocol by setting + * then to something other than -1. + * + * SetPS2Res: Set the resolution and sample rate for MSE_PS2 and MSE_XPS2 + * protocol types. + * + * SetBMRes: Set the resolution and sample rate for MSE_BM protocol types. + * + * SetMiscRes: Set the resolution and sample rate for MSE_MISC protocol types. + */ + +extern OSMouseInfoPtr xf86OSMouseInit(int flags); + +/* + * Mouse device record. This is shared by the mouse driver and the OSMouse + * layer. + */ + +typedef void (*PostMseEventProc)(InputInfoPtr pInfo, int buttons, + int dx, int dy, int dz, int dw); +typedef void (*MouseCommonOptProc)(InputInfoPtr pInfo); + +typedef struct _MouseDevRec { + PtrCtrlProcPtr Ctrl; + PostMseEventProc PostEvent; + MouseCommonOptProc CommonOptions; + DeviceIntPtr device; + const char * mseDevice; + const char * protocol; + int protocolID; + int oldProtocolID; /* hack */ + int class; + int mseModel; + int baudRate; + int oldBaudRate; + int sampleRate; + int lastButtons; + int threshold; /* acceleration */ + int num; + int den; + int buttons; /* # of buttons */ + int emulateState; /* automata state for 2 button mode */ + Bool emulate3Buttons; + Bool emulate3ButtonsSoft; + int emulate3Timeout;/* Timeout for 3 button emulation */ + Bool chordMiddle; + Bool flipXY; + int invX; + int invY; + int mouseFlags; /* Flags to Clear after opening + * mouse dev */ + int truebuttons; /* (not used) + * Arg to maintain before + * emulate3buttons timer callback */ + int resolution; + int negativeZ; /* button mask */ + int positiveZ; /* button mask */ + int negativeW; /* button mask */ + int positiveW; /* button mask */ + pointer buffer; /* usually an XISBuffer* */ + int protoBufTail; + unsigned char protoBuf[8]; + unsigned char protoPara[8]; + unsigned char inSync; /* driver in sync with datastream */ + pointer mousePriv; /* private area */ + InputInfoPtr pInfo; + int origProtocolID; + const char * origProtocol; + Bool emulate3Pending;/* timer waiting */ + CARD32 emulate3Expires;/* time to fire emulation code */ + Bool emulateWheel; + int wheelInertia; + int wheelButtonMask; + int negativeX; /* Button values. Unlike the Z and */ + int positiveX; /* W equivalents, these are button */ + int negativeY; /* values rather than button masks. */ + int positiveY; + int wheelYDistance; + int wheelXDistance; + Bool autoProbe; + checkMovementsProc checkMovements; + autoProbeProc autoProbeMouse; + collectDataProc collectData; + dataGoodProc dataGood; + int angleOffset; + pointer pDragLock; /* drag lock area */ +} MouseDevRec, *MouseDevPtr; + +/* Z axis mapping */ +#define MSE_NOZMAP 0 +#define MSE_MAPTOX -1 +#define MSE_MAPTOY -2 +#define MSE_MAPTOZ -3 +#define MSE_MAPTOW -4 + +/* Generalize for other axes. */ +#define MSE_NOAXISMAP MSE_NOZMAP + +#define MSE_MAXBUTTONS 12 +#define MSE_DFLTBUTTONS 3 + +#endif /* _XF86OSMOUSE_H_ */ diff --git a/hw/xfree86/os-support/xf86OSpriv.h b/hw/xfree86/os-support/xf86OSpriv.h new file mode 100644 index 000000000..c3224aeeb --- /dev/null +++ b/hw/xfree86/os-support/xf86OSpriv.h @@ -0,0 +1,27 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86OSpriv.h,v 1.5 2000/10/28 01:42:24 mvojkovi Exp $ */ + +#ifndef _XF86OSPRIV_H +#define _XF86OSPRIV_H + +typedef pointer (*MapMemProcPtr)(int, unsigned long, unsigned long, int); +typedef void (*UnmapMemProcPtr)(int, pointer, unsigned long); +typedef pointer (*SetWCProcPtr)(int, unsigned long, unsigned long, Bool, + MessageType); +typedef void (*ProtectMemProcPtr)(int, pointer, unsigned long, Bool); +typedef void (*UndoWCProcPtr)(int, pointer); +typedef void (*ReadSideEffectsProcPtr)(int, pointer, unsigned long); + +typedef struct { + Bool initialised; + MapMemProcPtr mapMem; + UnmapMemProcPtr unmapMem; + ProtectMemProcPtr protectMem; + SetWCProcPtr setWC; + UndoWCProcPtr undoWC; + ReadSideEffectsProcPtr readSideEffects; + Bool linearSupported; +} VidMemInfo, *VidMemInfoPtr; + +void xf86OSInitVidMem(VidMemInfoPtr); + +#endif /* _XF86OSPRIV_H */ diff --git a/hw/xfree86/os-support/xf86_ansic.h b/hw/xfree86/os-support/xf86_ansic.h new file mode 100644 index 000000000..03fa33417 --- /dev/null +++ b/hw/xfree86/os-support/xf86_ansic.h @@ -0,0 +1,352 @@ +/* + * Copyright 1997-2000 by The XFree86 Project, Inc + * + * 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 the above listed copyright holders + * not be used in advertising or publicity pertaining to distribution of + * the software without specific, written prior permission. The above listed + * copyright holders make no representations about the suitability of this + * software for any purpose. It is provided "as is" without express or + * implied warranty. + * + * THE ABOVE LISTED COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD + * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS, IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT HOLDERS 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/xf86_ansic.h,v 3.49.2.1 2003/03/13 04:10:49 tsi Exp $ */ + +#ifndef _XF86_ANSIC_H +#define _XF86_ANSIC_H + +/* Handle <stdarg.h> */ + +#ifndef IN_MODULE +# include <stdarg.h> +#else /* !IN_MODULE */ +# ifndef __OS2ELF__ +# include <stdarg.h> +# else /* __OS2ELF__ */ + /* EMX/gcc_elf under OS/2 does not have native header files */ +# if !defined (_VA_LIST) +# define _VA_LIST + typedef char *va_list; +# endif +# define _VA_ROUND(t) ((sizeof (t) + 3) & -4) +# if !defined (va_start) +# define va_start(ap,v) ap = (va_list)&v + ((sizeof (v) + 3) & -4) +# define va_end(ap) (ap = 0, (void)0) +# define va_arg(ap,t) (ap += _VA_ROUND (t), *(t *)(ap - _VA_ROUND (t))) +# endif +# endif /* __OS2ELF__ */ +#endif /* IN_MODULE */ + +/* + * The first set of definitions are required both for modules and + * libc_wrapper.c. + */ + +#if defined(XFree86LOADER) || defined(NEED_XF86_TYPES) + +#if !defined(SYSV) && !defined(SVR4) && !defined(Lynx) || defined(SCO) +#define HAVE_VSSCANF +#define HAVE_VFSCANF +#endif + +#ifndef NULL +#if (defined(SVR4) || defined(SYSV)) && !defined(__GNUC__) +#define NULL 0 +#else +#define NULL ((void *)0) +#endif +#endif +#ifndef EOF +#define EOF (-1) +#endif + +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +/* <limits.h> stuff */ +#define x_BITSPERBYTE 8 +#define x_BITS(type) (x_BITSPERBYTE * (int)sizeof(type)) +#define x_SHORTBITS x_BITS(short) +#define x_INTBITS x_BITS(int) +#define x_LONGBITS x_BITS(long) +#ifndef SHRT_MIN +#define SHRT_MIN ((short)(1 << (x_SHORTBITS - 1))) +#endif + +#ifndef FONTMODULE +#include "misc.h" +#endif +#include "xf86_libc.h" +#ifndef SHRT_MAX +#define SHRT_MAX ((short)~SHRT_MIN) +#endif +#ifndef USHRT_MAX +#define USHRT_MAX ((unsigned short)~0) +#endif +#ifndef MINSHORT +#define MINSHORT SHRT_MIN +#endif +#ifndef MAXSHORT +#define MAXSHORT SHRT_MAX +#endif +#ifndef INT_MIN +#define INT_MIN (1 << (x_INTBITS - 1)) +#endif +#ifndef INT_MAX +#define INT_MAX (~INT_MIN) +#endif +#ifndef UINT_MAX +#define UINT_MAX (~0) +#endif +#ifndef MININT +#define MININT INT_MIN +#endif +#ifndef MAXINT +#define MAXINT INT_MAX +#endif +#ifndef LONG_MIN +#define LONG_MIN ((long)(1 << (x_LONGBITS - 1))) +#endif +#ifndef LONG_MAX +#define LONG_MAX ((long)~LONG_MIN) +#endif +#ifndef ULONG_MAX +#define ULONG_MAX ((unsigned long)~0UL) +#endif +#ifndef MINLONG +#define MINLONG LONG_MIN +#endif +#ifndef MAXLONG +#define MAXLONG LONG_MAX +#endif + +#endif /* XFree86LOADER || NEED_XF86_TYPES */ + +#if defined(XFree86LOADER) || defined(NEED_XF86_PROTOTYPES) +/* + * ANSI C compilers only. + */ + +/* ANSI C emulation library */ + +extern void xf86abort(void); +extern int xf86abs(int); +extern double xf86acos(double); +extern double xf86asin(double); +extern double xf86atan(double); +extern double xf86atan2(double,double); +extern double xf86atof(const char*); +extern int xf86atoi(const char*); +extern long xf86atol(const char*); +extern void *xf86bsearch(const void *, const void *, xf86size_t, xf86size_t, + int (*)(const void *, const void *)); +extern double xf86ceil(double); +extern void* xf86calloc(xf86size_t,xf86size_t); +extern void xf86clearerr(XF86FILE*); +extern double xf86cos(double); +extern void xf86exit(int); +extern double xf86exp(double); +extern double xf86fabs(double); +extern int xf86fclose(XF86FILE*); +extern int xf86feof(XF86FILE*); +extern int xf86ferror(XF86FILE*); +extern int xf86fflush(XF86FILE*); +extern int xf86fgetc(XF86FILE*); +extern int xf86getc(XF86FILE*); +extern int xf86fgetpos(XF86FILE*,XF86fpos_t*); +extern char* xf86fgets(char*,INT32,XF86FILE*); +extern int xf86finite(double); +extern double xf86floor(double); +extern double xf86fmod(double,double); +extern XF86FILE* xf86fopen(const char*,const char*); +extern double xf86frexp(double, int*); +extern int xf86printf(const char*,...); +extern int xf86fprintf(XF86FILE*,const char*,...); +extern int xf86fputc(int,XF86FILE*); +extern int xf86fputs(const char*,XF86FILE*); +extern xf86size_t xf86fread(void*,xf86size_t,xf86size_t,XF86FILE*); +extern void xf86free(void*); +extern XF86FILE* xf86freopen(const char*,const char*,XF86FILE*); +#if defined(HAVE_VFSCANF) || !defined(NEED_XF86_PROTOTYPES) +extern int xf86fscanf(XF86FILE*,const char*,...); +#else +extern int xf86fscanf(/*XF86FILE*,const char*,char *,char *,char *,char *, + char *,char *,char *,char *,char *,char * */); +#endif +extern int xf86fseek(XF86FILE*,long,int); +extern int xf86fsetpos(XF86FILE*,const XF86fpos_t*); +extern long xf86ftell(XF86FILE*); +extern xf86size_t xf86fwrite(const void*,xf86size_t,xf86size_t,XF86FILE*); +extern char* xf86getenv(const char*); +extern int xf86isalnum(int); +extern int xf86isalpha(int); +extern int xf86iscntrl(int); +extern int xf86isdigit(int); +extern int xf86isgraph(int); +extern int xf86islower(int); +extern int xf86isprint(int); +extern int xf86ispunct(int); +extern int xf86isspace(int); +extern int xf86isupper(int); +extern int xf86isxdigit(int); +extern long xf86labs(long); +extern double xf86ldexp(double,int); +extern double xf86log(double); +extern double xf86log10(double); +extern void* xf86malloc(xf86size_t); +extern void* xf86memchr(const void*,int,xf86size_t); +extern int xf86memcmp(const void*,const void*,xf86size_t); +extern void* xf86memcpy(void*,const void*,xf86size_t); +extern void* xf86memmove(void*,const void*,xf86size_t); +extern void* xf86memset(void*,int,xf86size_t); +extern double xf86modf(double,double*); +extern void xf86perror(const char*); +extern double xf86pow(double,double); +extern void xf86qsort(void*, xf86size_t, xf86size_t, + int(*)(const void*, const void*)); +extern void* xf86realloc(void*,xf86size_t); +extern int xf86remove(const char*); +extern int xf86rename(const char*,const char*); +extern void xf86rewind(XF86FILE*); +extern int xf86setbuf(XF86FILE*,char*); +extern int xf86setvbuf(XF86FILE*,char*,int,xf86size_t); +extern double xf86sin(double); +extern int xf86sprintf(char*,const char*,...); +extern int xf86snprintf(char*,xf86size_t,const char*,...); +extern double xf86sqrt(double); +#if defined(HAVE_VSSCANF) || !defined(NEED_XF86_PROTOTYPES) +extern int xf86sscanf(char*,const char*,...); +#else +extern int xf86sscanf(/*char*,const char*,char *,char *,char *,char *, + char *,char *,char *,char *,char *,char * */); +#endif +extern char* xf86strcat(char*,const char*); +extern char* xf86strchr(const char*, int c); +extern int xf86strcmp(const char*,const char*); +extern int xf86strcasecmp(const char*,const char*); +extern char* xf86strcpy(char*,const char*); +extern xf86size_t xf86strcspn(const char*,const char*); +extern char* xf86strerror(int); +extern xf86size_t xf86strlen(const char*); +extern char* xf86strncat(char *, const char *, xf86size_t); +extern int xf86strncmp(const char*,const char*,xf86size_t); +extern int xf86strncasecmp(const char*,const char*,xf86size_t); +extern char* xf86strncpy(char*,const char*,xf86size_t); +extern char* xf86strpbrk(const char*,const char*); +extern char* xf86strrchr(const char*,int); +extern xf86size_t xf86strspn(const char*,const char*); +extern char* xf86strstr(const char*,const char*); +extern double xf86strtod(const char*,char**); +extern char* xf86strtok(char*,const char*); +extern long xf86strtol(const char*,char**,int); +extern unsigned long xf86strtoul(const char*,char**,int); +extern double xf86tan(double); +extern XF86FILE* xf86tmpfile(void); +extern char* xf86tmpnam(char*); +extern int xf86tolower(int); +extern int xf86toupper(int); +extern int xf86ungetc(int,XF86FILE*); +extern int xf86vfprintf(XF86FILE*,const char*,va_list); +extern int xf86vsprintf(char*,const char*,va_list); +extern int xf86vsnprintf(char*,xf86size_t,const char*,va_list); + +extern int xf86open(const char*, int,...); +extern int xf86close(int); +extern long xf86lseek(int, long, int); +extern int xf86ioctl(int, unsigned long, pointer); +extern xf86ssize_t xf86read(int, void *, xf86size_t); +extern xf86ssize_t xf86write(int, const void *, xf86size_t); +extern void* xf86mmap(void*, xf86size_t, int, int, int, xf86size_t /* off_t */); +extern int xf86munmap(void*, xf86size_t); +extern int xf86stat(const char *, struct xf86stat *); +extern int xf86fstat(int, struct xf86stat *); +extern int xf86access(const char *, int); +extern int xf86errno; +extern int xf86GetErrno(void); + +extern double xf86HUGE_VAL; + +extern double xf86hypot(double,double); + +/* non-ANSI C functions */ +extern XF86DIR* xf86opendir(const char*); +extern int xf86closedir(XF86DIR*); +extern XF86DIRENT* xf86readdir(XF86DIR*); +extern void xf86rewinddir(XF86DIR*); +extern void xf86bcopy(const void*,void*,xf86size_t); +extern int xf86ffs(int); +extern char* xf86strdup(const char*); +extern void xf86bzero(void*,unsigned int); +extern int xf86execl(const char *, const char *, ...); +extern long xf86fpossize(void); +extern int xf86chmod(const char *, xf86mode_t); +extern int xf86chown(const char *, xf86uid_t, xf86gid_t); +extern xf86uid_t xf86geteuid(void); +extern xf86gid_t xf86getegid(void); +extern int xf86getpid(void); +extern int xf86mknod(const char *, xf86mode_t, xf86dev_t); +extern int xf86mkdir(const char *, xf86mode_t); +unsigned int xf86sleep(unsigned int seconds); +/* sysv IPC */ +extern int xf86shmget(xf86key_t key, int size, int xf86shmflg); +extern char * xf86shmat(int id, char *addr, int xf86shmflg); +extern int xf86shmdt(char *addr); +extern int xf86shmctl(int id, int xf86cmd, pointer buf); + +extern int xf86setjmp(xf86jmp_buf env); +extern int xf86setjmp0(xf86jmp_buf env); +extern int xf86setjmp1(xf86jmp_buf env, int); +extern int xf86setjmp1_arg2(void); +extern int xf86setjmperror(xf86jmp_buf env); +extern int xf86getjmptype(void); +extern void xf86longjmp(xf86jmp_buf env, int val); +#define xf86setjmp_macro(env) \ + (xf86getjmptype() == 0 ? xf86setjmp0((env)) : \ + (xf86getjmptype() == 1 ? xf86setjmp1((env), xf86setjmp1_arg2()) : \ + xf86setjmperror((env)))) + +#else /* XFree86LOADER || NEED_XF86_PROTOTYPES */ +#include <unistd.h> +#include <stdio.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <fcntl.h> +#include <ctype.h> +#ifdef HAVE_SYSV_IPC +#include <sys/ipc.h> +#include <sys/shm.h> +#endif +#include <sys/stat.h> +#define stat_t struct stat +#endif /* XFree86LOADER || NEED_XF86_PROTOTYPES */ + +/* + * These things are always required by drivers (but not by libc_wrapper.c), + * even for a static server because some OSs don't provide them. + */ + +extern int xf86getpagesize(void); +extern void xf86usleep(unsigned long); +extern void xf86getsecs(long *, long *); +#ifndef DONT_DEFINE_WRAPPERS +#undef getpagesize +#define getpagesize() xf86getpagesize() +#undef usleep +#define usleep(ul) xf86usleep(ul) +#undef getsecs +#define getsecs(a, b) xf86getsecs(a, b) +#endif +#endif /* _XF86_ANSIC_H */ diff --git a/hw/xfree86/os-support/xf86_libc.h b/hw/xfree86/os-support/xf86_libc.h new file mode 100644 index 000000000..b97599ed5 --- /dev/null +++ b/hw/xfree86/os-support/xf86_libc.h @@ -0,0 +1,672 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86_libc.h,v 3.56 2003/02/22 06:00:39 dawes Exp $ */ + + + +/* + * This file is an attempt to make developing code for the new loadable module + * architecure simpler. It tries to use macros to hide all libc wrappers so + * that all that is needed to "port" a module to this architecture is to + * include this one header file + * + * Revision history: + * + * + * 0.4 Apr 12 1997 add the ANSI defines + * 0.3 Feb 24 1997 handle getenv + * 0.2 Feb 24 1997 hide few FILE functions + * 0.1 Feb 24 1997 hide the trivial functions mem* str* + */ + +#ifndef XF86_LIBC_H +#define XF86_LIBC_H 1 + +#include "Xfuncs.h" + +/* + * The first set of definitions are required both for modules and + * libc_wrapper.c. + */ + +#if defined(XFree86LOADER) || defined(NEED_XF86_TYPES) + +/* + * First, the new data types + * + * note: if some pointer is declared "opaque" here, pass it between + * xf86* functions only, and don't rely on it having a whatever internal + * structure, even if some source file might reveal the existence of + * such a structure. + */ +typedef void XF86FILE; /* opaque FILE replacement */ +extern XF86FILE* xf86stdin; +extern XF86FILE* xf86stdout; +extern XF86FILE* xf86stderr; + +typedef void XF86fpos_t; /* opaque fpos_t replacement */ + +#define _XF86NAMELEN 263 /* enough for a larger filename */ + /* (divisble by 8) */ +typedef void XF86DIR; /* opaque DIR replacement */ + +/* Note: the following is POSIX! POSIX only requires the d_name member. + * Normal Unix has often a number of other members, but don't rely on that + */ +struct _xf86dirent { /* types in struct dirent/direct: */ + char d_name[_XF86NAMELEN+1]; /* char [MAXNAMLEN]; might be smaller or unaligned */ +}; +typedef struct _xf86dirent XF86DIRENT; + +typedef unsigned long xf86size_t; +typedef signed long xf86ssize_t; +typedef unsigned long xf86dev_t; +typedef unsigned int xf86mode_t; +typedef unsigned int xf86uid_t; +typedef unsigned int xf86gid_t; + +struct xf86stat { + xf86dev_t st_rdev; /* This is incomplete, and makes assumptions */ +}; + +/* sysv IPC */ +typedef int xf86key_t; + +/* setjmp/longjmp */ +typedef int xf86jmp_buf[1024]; + +/* for setvbuf */ +#define XF86_IONBF 1 +#define XF86_IOFBF 2 +#define XF86_IOLBF 3 + +/* for open (XXX not complete) */ +#define XF86_O_RDONLY 0x0000 +#define XF86_O_WRONLY 0x0001 +#define XF86_O_RDWR 0x0002 +#define XF86_O_CREAT 0x0200 + +/* for mmap */ +#define XF86_PROT_EXEC 0x0001 +#define XF86_PROT_READ 0x0002 +#define XF86_PROT_WRITE 0x0004 +#define XF86_PROT_NONE 0x0008 +#define XF86_MAP_FIXED 0x0001 +#define XF86_MAP_SHARED 0x0002 +#define XF86_MAP_PRIVATE 0x0004 +#define XF86_MAP_32BIT 0x0040 +#define XF86_MAP_FAILED ((void *)-1) + +/* for fseek */ +#define XF86_SEEK_SET 0 +#define XF86_SEEK_CUR 1 +#define XF86_SEEK_END 2 + +/* for access */ +#define XF86_R_OK 0 +#define XF86_W_OK 1 +#define XF86_X_OK 2 +#define XF86_F_OK 3 + +/* for chmod */ +#define XF86_S_ISUID 04000 /* set user ID on execution */ +#define XF86_S_ISGID 02000 /* set group ID on execution */ +#define XF86_S_ISVTX 01000 /* sticky bit */ +#define XF86_S_IRUSR 00400 /* read by owner */ +#define XF86_S_IWUSR 00200 /* write by owner */ +#define XF86_S_IXUSR 00100 /* execute/search by owner */ +#define XF86_S_IRGRP 00040 /* read by group */ +#define XF86_S_IWGRP 00020 /* write by group */ +#define XF86_S_IXGRP 00010 /* execute/search by group */ +#define XF86_S_IROTH 00004 /* read by others */ +#define XF86_S_IWOTH 00002 /* write by others */ +#define XF86_S_IXOTH 00001 /* execute/search by others */ + +/* for mknod */ +#define XF86_S_IFREG 0010000 +#define XF86_S_IFCHR 0020000 +#define XF86_S_IFBLK 0040000 +#define XF86_S_IFIFO 0100000 + +/* + * errno values + * They start at 1000 just so they don't match real errnos at all + */ +#define xf86_UNKNOWN 1000 +#define xf86_EACCES 1001 +#define xf86_EAGAIN 1002 +#define xf86_EBADF 1003 +#define xf86_EEXIST 1004 +#define xf86_EFAULT 1005 +#define xf86_EINTR 1006 +#define xf86_EINVAL 1007 +#define xf86_EISDIR 1008 +#define xf86_ELOOP 1009 +#define xf86_EMFILE 1010 +#define xf86_ENAMETOOLONG 1011 +#define xf86_ENFILE 1012 +#define xf86_ENOENT 1013 +#define xf86_ENOMEM 1014 +#define xf86_ENOSPC 1015 +#define xf86_ENOTDIR 1016 +#define xf86_EPIPE 1017 +#define xf86_EROFS 1018 +#define xf86_ETXTBSY 1019 +#define xf86_ENOTTY 1020 +#define xf86_ENOSYS 1021 +#define xf86_EBUSY 1022 +#define xf86_ENODEV 1023 +#define xf86_EIO 1024 + +/* sysv IPV */ +/* xf86shmget() */ +#define XF86IPC_CREAT 01000 +#define XF86IPC_EXCL 02000 +#define XF86IPC_NOWAIT 04000 +#define XF86SHM_R 0400 +#define XF86SHM_W 0200 +#define XF86IPC_PRIVATE ((xf86key_t)0) +/* xf86shmat() */ +#define XF86SHM_RDONLY 010000 /* attach read-only else read-write */ +#define XF86SHM_RND 020000 /* round attach address to SHMLBA */ +#define XF86SHM_REMAP 040000 /* take-over region on attach */ +/* xf86shmclt() */ +#define XF86IPC_RMID 0 + +#endif /* defined(XFree86LOADER) || defined(NEED_XF86_TYPES) */ + +/* + * the rest of this file should only be included for code that is supposed + * to go into modules + */ + +#if defined(XFree86LOADER) && !defined(DONT_DEFINE_WRAPPERS) + +#undef abort +#define abort() xf86abort() +#undef abs +#define abs(i) xf86abs(i) +#undef acos +#define acos(d) xf86acos(d) +#undef asin +#define asin(d) xf86asin(d) +#undef atan +#define atan(d) xf86atan(d) +#undef atan2 +#define atan2(d1,d2) xf86atan2(d1,d2) +#undef atof +#define atof(ccp) xf86atof(ccp) +#undef atoi +#define atoi(ccp) xf86atoi(ccp) +#undef atol +#define atol(ccp) xf86atol(ccp) +#undef bsearch +#define bsearch(a,b,c,d,e) xf86bsearch(a,b,c,d,e) +#undef ceil +#define ceil(d) xf86ceil(d) +#undef calloc +#define calloc(I1,I2) xf86calloc(I1,I2) +#undef clearerr +#define clearerr(FP) xf86clearerr(FP) +#undef cos +#define cos(d) xf86cos(d) +#undef exit +#define exit(i) xf86exit(i) +#undef exp +#define exp(d) xf86exp(d) +#undef fabs +#define fabs(d) xf86fabs(d) +#undef fclose +#define fclose(FP) xf86fclose(FP) +#undef feof +#define feof(FP) xf86feof(FP) +#undef ferror +#define ferror(FP) xf86ferror(FP) +#undef fflush +#define fflush(FP) xf86fflush(FP) +#undef fgetc +#define fgetc(FP) xf86fgetc(FP) +#undef getc +#define getc(FP) xf86getc(FP) +#undef fgetpos +#define fgetpos(FP,fpp) xf86fgetpos(FP,fpp) +#undef fgets +#define fgets(cp,i,FP) xf86fgets(cp,i,FP) +#undef finite +#define finite(d) xf86finite(d) +#undef floor +#define floor(d) xf86floor(d) +#undef fmod +#define fmod(d1,d2) xf86fmod(d1,d2) +#undef fopen +#define fopen(ccp1,ccp2) xf86fopen(ccp1,ccp2) +#undef printf +#define printf xf86printf +#undef fprintf +#define fprintf xf86fprintf +#undef fputc +#define fputc(i,FP) xf86fputc(i,FP) +#undef fputs +#define fputs(ccp,FP) xf86fputs(ccp,FP) +#undef fread +#define fread(vp,I1,I2,FP) xf86fread(vp,I1,I2,FP) +#undef free +#define free(vp) xf86free(vp) +#undef freopen +#define freopen(ccp1,ccp2,FP) xf86freopen(ccp1,ccp2,FP) +#undef frexp +#define frexp(x,exp) xf86frexp(x,exp) +#undef fscanf +#define fscanf xf86fscanf +#undef fseek +#define fseek(FP,l,i) xf86fseek(FP,l,i) +#undef fsetpos +#define fsetpos(FP,cfpp) xf86fsetpos(FP,cfpp) +#undef ftell +#define ftell(FP) xf86ftell(FP) +#undef fwrite +#define fwrite(cvp,I1,I2,FP) xf86fwrite(cvp,I1,I2,FP) +#undef getenv +#define getenv(ccp) xf86getenv(ccp) +#undef isalnum +#define isalnum(i) xf86isalnum(i) +#undef isalpha +#define isalpha(i) xf86isalpha(i) +#undef iscntrl +#define iscntrl(i) xf86iscntrl(i) +#undef isdigit +#define isdigit(i) xf86isdigit(i) +#undef isgraph +#define isgraph(i) xf86isgraph(i) +#undef islower +#define islower(i) xf86islower(i) +#undef isprint +#define isprint(i) xf86isprint(i) +#undef ispunct +#define ispunct(i) xf86ispunct(i) +#undef isspace +#define isspace(i) xf86isspace(i) +#undef isupper +#define isupper(i) xf86isupper(i) +#undef isxdigit +#define isxdigit(i) xf86isxdigit(i) +#undef labs +#define labs(l) xf86labs(l) +#undef ldexp +#define ldexp(x, exp) xf86ldexp(x, exp) +#undef log +#define log(d) xf86log(d) +#undef log10 +#define log10(d) xf86log10(d) +#undef malloc +#define malloc(I) xf86malloc(I) +#undef memchr +#define memchr(cvp,i,I) xf86memchr(cvp,i,I) +#undef memcmp +#define memcmp(cvp1,cvp2,I) xf86memcmp(cvp1,cvp2,I) +#undef memcpy +#define memcpy(vp,cvp,I) xf86memcpy(vp,cvp,I) +#undef memmove +#define memmove(vp,cvp,I) xf86memmove(vp,cvp,I) +#undef memset +#define memset(vp,int,I) xf86memset(vp,int,I) +#undef modf +#define modf(d,dp) xf86modf(d,dp) +#undef perror +#define perror(ccp) xf86perror(ccp) +#undef pow +#define pow(d1,d2) xf86pow(d1,d2) +#undef realloc +#define realloc(vp,I) xf86realloc(vp,I) +#undef remove +#define remove(ccp) xf86remove(ccp) +#undef rename +#define rename(ccp1,ccp2) xf86rename(ccp1,ccp2) +#undef rewind +#define rewind(FP) xf86rewind(FP) +#undef setbuf +#define setbuf(FP,cp) xf86setbuf(FP,cp) +#undef setvbuf +#define setvbuf(FP,cp,i,I) xf86setvbuf(FP,cp,i,I) +#undef sin +#define sin(d) xf86sin(d) +#undef snprintf +#define snprintf xf86snprintf +#undef sprintf +#define sprintf xf86sprintf +#undef sqrt +#define sqrt(d) xf86sqrt(d) +#undef sscanf +#define sscanf xf86sscanf +#undef strcat +#define strcat(cp,ccp) xf86strcat(cp,ccp) +#undef strcmp +#define strcmp(ccp1,ccp2) xf86strcmp(ccp1,ccp2) +#undef strcasecmp +#define strcasecmp(ccp1,ccp2) xf86strcasecmp(ccp1,ccp2) +#undef strcpy +#define strcpy(cp,ccp) xf86strcpy(cp,ccp) +#undef strcspn +#define strcspn(ccp1,ccp2) xf86strcspn(ccp1,ccp2) +#undef strerror +#define strerror(i) xf86strerror(i) +#undef strlen +#define strlen(ccp) xf86strlen(ccp) +#undef strncmp +#define strncmp(ccp1,ccp2,I) xf86strncmp(ccp1,ccp2,I) +#undef strncasecmp +#define strncasecmp(ccp1,ccp2,I) xf86strncasecmp(ccp1,ccp2,I) +#undef strncpy +#define strncpy(cp,ccp,I) xf86strncpy(cp,ccp,I) +#undef strpbrk +#define strpbrk(ccp1,ccp2) xf86strpbrk(ccp1,ccp2) +#undef strchr +#define strchr(ccp,i) xf86strchr(ccp,i) +#undef strrchr +#define strrchr(ccp,i) xf86strrchr(ccp,i) +#undef strspn +#define strspn(ccp1,ccp2) xf86strspn(ccp1,ccp2) +#undef strstr +#define strstr(ccp1,ccp2) xf86strstr(ccp1,ccp2) +#undef srttod +#define strtod(ccp,cpp) xf86strtod(ccp,cpp) +#undef strtok +#define strtok(cp,ccp) xf86strtok(cp,ccp) +#undef strtol +#define strtol(ccp,cpp,i) xf86strtol(ccp,cpp,i) +#undef strtoul +#define strtoul(ccp,cpp,i) xf86strtoul(ccp,cpp,i) +#undef tan +#define tan(d) xf86tan(d) +#undef tmpfile +#define tmpfile() xf86tmpfile() +#undef tolower +#define tolower(i) xf86tolower(i) +#undef toupper +#define toupper(i) xf86toupper(i) +#undef ungetc +#define ungetc(i,FP) xf86ungetc(i,FP) +#undef vfprinf +#define vfprintf xf86vfprintf +#undef vsnprintf +#define vsnprintf xf86vsnprintf +#undef vsprintf +#define vsprintf xf86vsprintf +/* XXX Disable assert as if NDEBUG was defined */ +/* Some X headers defined this away too */ +#undef assert +#define assert(a) ((void)0) +#undef HUGE_VAL +#define HUGE_VAL xf86HUGE_VAL + +#undef hypot +#define hypot(x,y) xf86hypot(x,y) + +#undef qsort +#define qsort(b, n, s, f) xf86qsort(b, n, s, f) + +/* non-ANSI C functions */ +#undef opendir +#define opendir(cp) xf86opendir(cp) +#undef closedir +#define closedir(DP) xf86closedir(DP) +#undef readdir +#define readdir(DP) xf86readdir(DP) +#undef rewinddir +#define rewinddir(DP) xf86rewinddir(DP) +#undef bcopy +#define bcopy(vp,cvp,I) xf86memmove(cvp,vp,I) +#undef ffs +#define ffs(i) xf86ffs(i) +#undef strdup +#define strdup(ccp) xf86strdup(ccp) +#undef bzero +#define bzero(vp,ui) xf86bzero(vp,ui) +#undef execl +#define execl xf86execl +#undef chmod +#define chmod(a,b) xf86chmod(a,b) +#undef chown +#define chown(a,b,c) xf86chown(a,b,c) +#undef geteuid +#define geteuid xf86geteuid +#undef getegid +#define getegid xf86getegid +#undef getpid +#define getpid xf86getpid +#undef mknod +#define mknod(a,b,c) xf86mknod(a,b,c) +#undef sleep +#define sleep(a) xf86sleep(a) +#undef mkdir +#define mkdir(a,b) xf86mkdir(a,b) +#undef getpagesize +#define getpagesize xf86getpagesize +#undef shmget +#define shmget(a,b,c) xf86shmget(a,b,c) +#undef shmat +#define shmat(a,b,c) xf86shmat(a,b,c) +#undef shmdt +#define shmdt(a) xf86shmdt(a) +#undef shmctl +#define shmctl(a,b,c) xf86shmctl(a,b,c) + +#undef S_ISUID +#define S_ISUID XF86_S_ISUID +#undef S_ISGID +#define S_ISGID XF86_S_ISGID +#undef S_ISVTX +#define S_ISVTX XF86_S_ISVTX +#undef S_IRUSR +#define S_IRUSR XF86_S_IRUSR +#undef S_IWUSR +#define S_IWUSR XF86_S_IWUSR +#undef S_IXUSR +#define S_IXUSR XF86_S_IXUSR +#undef S_IRGRP +#define S_IRGRP XF86_S_IRGRP +#undef S_IWGRP +#define S_IWGRP XF86_S_IWGRP +#undef S_IXGRP +#define S_IXGRP XF86_S_IXGRP +#undef S_IROTH +#define S_IROTH XF86_S_IROTH +#undef S_IWOTH +#define S_IWOTH XF86_S_IWOTH +#undef S_IXOTH +#define S_IXOTH XF86_S_IXOTH +#undef S_IFREG +#define S_IFREG XF86_S_IFREG +#undef S_IFCHR +#define S_IFCHR XF86_S_IFCHR +#undef S_IFBLK +#define S_IFBLK XF86_S_IFBLK +#undef S_IFIFO +#define S_IFIFO XF86_S_IFIFO + +/* some types */ +#undef FILE +#define FILE XF86FILE +#undef fpos_t +#define fpos_t XF86fpos_t +#undef DIR +#define DIR XF86DIR +#undef DIRENT +#define DIRENT XF86DIRENT +#undef size_t +#define size_t xf86size_t +#undef ssize_t +#define ssize_t xf86ssize_t +#undef dev_t +#define dev_t xf86dev_t +#undef mode_t +#define mode_t xf86mode_t +#undef uid_t +#define uid_t xf86uid_t +#undef gid_t +#define gid_t xf86gid_t +#undef stat_t +#define stat_t struct xf86stat + +#undef ulong +#define ulong unsigned long + +/* + * There should be no need to #undef any of these. If they are already + * defined it is because some illegal header has been included. + */ + +/* some vars */ +#undef stdin +#define stdin xf86stdin +#undef stdout +#define stdout xf86stdout +#undef stderr +#define stderr xf86stderr + +#undef SEEK_SET +#define SEEK_SET XF86_SEEK_SET +#undef SEEK_CUR +#define SEEK_CUR XF86_SEEK_CUR +#undef SEEK_END +#define SEEK_END XF86_SEEK_END + +/* + * XXX Basic I/O functions BAD,BAD,BAD! + */ +#define open xf86open +#define close(a) xf86close(a) +#define lseek(a,b,c) xf86lseek(a,b,c) +#define ioctl(a,b,c) xf86ioctl(a,b,c) +#define read(a,b,c) xf86read(a,b,c) +#define write(a,b,c) xf86write(a,b,c) +#define mmap(a,b,c,d,e,f) xf86mmap(a,b,c,d,e,f) +#define munmap(a,b) xf86munmap(a,b) +#define stat(a,b) xf86stat(a,b) +#define fstat(a,b) xf86fstat(a,b) +#define access(a,b) xf86access(a,b) +#undef O_RDONLY +#define O_RDONLY XF86_O_RDONLY +#undef O_WRONLY +#define O_WRONLY XF86_O_WRONLY +#undef O_RDWR +#define O_RDWR XF86_O_RDWR +#undef O_CREAT +#define O_CREAT XF86_O_CREAT +#undef PROT_EXEC +#define PROT_EXEC XF86_PROT_EXEC +#undef PROT_READ +#define PROT_READ XF86_PROT_READ +#undef PROT_WRITE +#define PROT_WRITE XF86_PROT_WRITE +#undef PROT_NONE +#define PROT_NONE XF86_PROT_NONE +#undef MAP_FIXED +#define MAP_FIXED XF86_MAP_FIXED +#undef MAP_SHARED +#define MAP_SHARED XF86_MAP_SHARED +#undef MAP_PRIVATE +#define MAP_PRIVATE XF86_MAP_PRIVATE +#undef MAP_FAILED +#define MAP_FAILED XF86_MAP_FAILED +#undef R_OK +#define R_OK XF86_R_OK +#undef W_OK +#define W_OK XF86_W_OK +#undef X_OK +#define X_OK XF86_X_OK +#undef F_OK +#define F_OK XF86_F_OK +#undef errno +#define errno xf86errno +#undef putchar +#define putchar(i) xf86fputc(i, xf86stdout) +#undef puts +#define puts(s) xf86fputs(s, xf86stdout) + +#undef EACCES +#define EACCES xf86_EACCES +#undef EAGAIN +#define EAGAIN xf86_EAGAIN +#undef EBADF +#define EBADF xf86_EBADF +#undef EEXIST +#define EEXIST xf86_EEXIST +#undef EFAULT +#define EFAULT xf86_EFAULT +#undef EINTR +#define EINTR xf86_EINTR +#undef EINVAL +#define EINVAL xf86_EINVAL +#undef EISDIR +#define EISDIR xf86_EISDIR +#undef ELOOP +#define ELOOP xf86_ELOOP +#undef EMFILE +#define EMFILE xf86_EMFILE +#undef ENAMETOOLONG +#define ENAMETOOLONG xf86_ENAMETOOLONG +#undef ENFILE +#define ENFILE xf86_ENFILE +#undef ENOENT +#define ENOENT xf86_ENOENT +#undef ENOMEM +#define ENOMEM xf86_ENOMEM +#undef ENOSPC +#define ENOSPC xf86_ENOSPC +#undef ENOTDIR +#define ENOTDIR xf86_ENOTDIR +#undef EPIPE +#define EPIPE xf86_EPIPE +#undef EROFS +#define EROFS xf86_EROFS +#undef ETXTBSY +#define ETXTBSY xf86_ETXTBSY +#undef ENOTTY +#define ENOTTY xf86_ENOTTY +#undef ENOSYS +#define ENOSYS xf86_ENOSYS +#undef EBUSY +#define EBUSY xf86_EBUSY +#undef ENODEV +#define ENODEV xf86_ENODEV +#undef EIO +#define EIO xf86_EIO + +/* IPC stuff */ +#undef SHM_RDONLY +#define SHM_RDONLY XF86SHM_RDONLY +#undef SHM_RND +#define SHM_RND XF86SHM_RND +#undef SHM_REMAP +#define SHM_REMAP XF86SHM_REMAP +#undef IPC_RMID +#define IPC_RMID XF86IPC_RMID +#undef IPC_CREAT +#define IPC_CREAT XF86IPC_CREAT +#undef IPC_EXCL +#define IPC_EXCL XF86IPC_EXCL +#undef PC_NOWAIT +#define IPC_NOWAIT XF86IPC_NOWAIT +#undef SHM_R +#define SHM_R XF86SHM_R +#undef SHM_W +#define SHM_W XF86SHM_W +#undef IPC_PRIVATE +#define IPC_PRIVATE XF86IPC_PRIVATE + +/* Some ANSI macros */ +#undef FILENAME_MAX +#define FILENAME_MAX 1024 + +#endif /* XFree86LOADER && !DONT_DEFINE_WRAPPERS */ + +#if defined(XFree86LOADER) && \ + (!defined(DONT_DEFINE_WRAPPERS) || defined(DEFINE_SETJMP_WRAPPERS)) +#undef setjmp +#define setjmp(a) xf86setjmp_macro(a) +#undef longjmp +#define longjmp(a,b) xf86longjmp(a,b) +#undef jmp_buf +#define jmp_buf xf86jmp_buf +#endif + +#endif /* XF86_LIBC_H */ |