1/* 2 * Copyright 1990,91 by Thomas Roell, Dinkelscherben, Germany 3 * Copyright 1993 by David Wexelblat <dwex@goblin.org> 4 * Copyright 1999 by David Holland <davidh@iquest.net> 5 * 6 * Permission to use, copy, modify, distribute, and sell this software and its 7 * documentation for any purpose is hereby granted without fee, provided that 8 * the above copyright notice appear in all copies and that both that copyright 9 * notice and this permission notice appear in supporting documentation, and 10 * that the names of the copyright holders not be used in advertising or 11 * publicity pertaining to distribution of the software without specific, 12 * written prior permission. The copyright holders make no representations 13 * about the suitability of this software for any purpose. It is provided "as 14 * is" without express or implied warranty. 15 * 16 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 17 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT 18 * SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR 19 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 20 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 21 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 22 * OF THIS SOFTWARE. 23 * 24 */ 25/* Copyright (c) 2008, Oracle and/or its affiliates. All rights reserved. 26 * 27 * Permission is hereby granted, free of charge, to any person obtaining a 28 * copy of this software and associated documentation files (the "Software"), 29 * to deal in the Software without restriction, including without limitation 30 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 31 * and/or sell copies of the Software, and to permit persons to whom the 32 * Software is furnished to do so, subject to the following conditions: 33 * 34 * The above copyright notice and this permission notice (including the next 35 * paragraph) shall be included in all copies or substantial portions of the 36 * Software. 37 * 38 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 39 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 40 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 41 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 42 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 43 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 44 * DEALINGS IN THE SOFTWARE. 45 */ 46 47#ifdef HAVE_XORG_CONFIG_H 48#include <xorg-config.h> 49#endif 50 51#include <sys/types.h> /* get __x86 definition if not set by compiler */ 52 53#if defined(__i386__) || defined(__i386) || defined(__x86) 54# define _NEED_SYSI86 55#endif 56#include "xf86.h" 57#include "xf86Priv.h" 58#include "xf86_OSlib.h" 59#include "xf86OSpriv.h" 60#include <sys/mman.h> 61 62/***************************************************************************/ 63/* Video Memory Mapping section */ 64/***************************************************************************/ 65 66static char *apertureDevName = NULL; 67static int apertureDevFD_ro = -1; 68static int apertureDevFD_rw = -1; 69 70static Bool 71solOpenAperture(void) 72{ 73 if (apertureDevName == NULL) 74 { 75 apertureDevName = "/dev/xsvc"; 76 if ((apertureDevFD_rw = open(apertureDevName, O_RDWR)) < 0) 77 { 78 xf86MsgVerb(X_WARNING, 0, 79 "solOpenAperture: failed to open %s (%s)\n", 80 apertureDevName, strerror(errno)); 81 apertureDevName = "/dev/fbs/aperture"; 82 apertureDevFD_rw = open(apertureDevName, O_RDWR); 83 } 84 apertureDevFD_ro = open(apertureDevName, O_RDONLY); 85 86 if ((apertureDevFD_rw < 0) || (apertureDevFD_ro < 0)) 87 { 88 xf86MsgVerb(X_WARNING, 0, 89 "solOpenAperture: failed to open %s (%s)\n", 90 apertureDevName, strerror(errno)); 91 xf86MsgVerb(X_WARNING, 0, 92 "solOpenAperture: either /dev/fbs/aperture" 93 " or /dev/xsvc required\n"); 94 95 apertureDevName = NULL; 96 97 if (apertureDevFD_rw >= 0) 98 { 99 close(apertureDevFD_rw); 100 } 101 apertureDevFD_rw = -1; 102 103 if (apertureDevFD_ro >= 0) 104 { 105 close(apertureDevFD_ro); 106 } 107 apertureDevFD_ro = -1; 108 109 return FALSE; 110 } 111 } 112 return TRUE; 113} 114 115static pointer 116solMapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int Flags) 117{ 118 pointer base; 119 int fd; 120 int prot; 121 122 if (Flags & VIDMEM_READONLY) 123 { 124 fd = apertureDevFD_ro; 125 prot = PROT_READ; 126 } 127 else 128 { 129 fd = apertureDevFD_rw; 130 prot = PROT_READ | PROT_WRITE; 131 } 132 133 if (fd < 0) 134 { 135 xf86DrvMsg(ScreenNum, X_ERROR, 136 "solMapVidMem: failed to open %s (%s)\n", 137 apertureDevName, strerror(errno)); 138 return NULL; 139 } 140 141 base = mmap(NULL, Size, prot, MAP_SHARED, fd, (off_t)Base); 142 143 if (base == MAP_FAILED) { 144 xf86DrvMsg(ScreenNum, X_ERROR, 145 "solMapVidMem: failed to mmap %s (0x%08lx,0x%lx) (%s)\n", 146 apertureDevName, Base, Size, strerror(errno)); 147 return NULL; 148 } 149 150 return base; 151} 152 153/* ARGSUSED */ 154static void 155solUnMapVidMem(int ScreenNum, pointer Base, unsigned long Size) 156{ 157 if (munmap(Base, Size) != 0) { 158 xf86DrvMsgVerb(ScreenNum, X_WARNING, 0, 159 "solUnMapVidMem: failed to unmap %s" 160 " (0x%p,0x%lx) (%s)\n", 161 apertureDevName, Base, Size, 162 strerror(errno)); 163 } 164} 165 166_X_HIDDEN void 167xf86OSInitVidMem(VidMemInfoPtr pVidMem) 168{ 169 pVidMem->linearSupported = solOpenAperture(); 170 if (pVidMem->linearSupported) { 171 pVidMem->mapMem = solMapVidMem; 172 pVidMem->unmapMem = solUnMapVidMem; 173 } else { 174 xf86MsgVerb(X_WARNING, 0, 175 "xf86OSInitVidMem: linear memory access disabled\n"); 176 } 177 pVidMem->initialised = TRUE; 178} 179 180/* 181 * Read BIOS via mmap()ing physical memory. 182 */ 183int 184xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf, 185 int Len) 186{ 187 unsigned char *ptr; 188 int psize; 189 int mlen; 190 191 psize = getpagesize(); 192 Offset += Base & (psize - 1); 193 Base &= ~(psize - 1); 194 mlen = (Offset + Len + psize - 1) & ~(psize - 1); 195 196 if (solOpenAperture() == FALSE) 197 { 198 xf86Msg(X_WARNING, 199 "xf86ReadBIOS: Failed to open aperture to read BIOS\n"); 200 return -1; 201 } 202 203 ptr = (unsigned char *)mmap(NULL, mlen, PROT_READ, 204 MAP_SHARED, apertureDevFD_ro, (off_t)Base); 205 if (ptr == MAP_FAILED) 206 { 207 xf86Msg(X_WARNING, "xf86ReadBIOS: %s mmap failed [0x%08lx, 0x%04x]\n", 208 apertureDevName, Base, mlen); 209 return -1; 210 } 211 212 (void)memcpy(Buf, (void *)(ptr + Offset), Len); 213 if (munmap((caddr_t)ptr, mlen) != 0) { 214 xf86MsgVerb(X_WARNING, 0, 215 "xf86ReadBIOS: failed to unmap %s (0x%p,0x%x) (%s)\n", 216 apertureDevName, ptr, mlen, strerror(errno)); 217 } 218 219 return Len; 220} 221 222 223/***************************************************************************/ 224/* I/O Permissions section */ 225/***************************************************************************/ 226 227#if defined(__i386__) || defined(__i386) || defined(__x86) 228static Bool ExtendedEnabled = FALSE; 229#endif 230 231Bool 232xf86EnableIO(void) 233{ 234#if defined(__i386__) || defined(__i386) || defined(__x86) 235 if (ExtendedEnabled) 236 return TRUE; 237 238 if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0) { 239 xf86Msg(X_WARNING, "xf86EnableIOPorts: Failed to set IOPL for I/O\n"); 240 return FALSE; 241 } 242 ExtendedEnabled = TRUE; 243#endif /* i386 */ 244 return TRUE; 245} 246 247void 248xf86DisableIO(void) 249{ 250#if defined(__i386__) || defined(__i386) || defined(__x86) 251 if(!ExtendedEnabled) 252 return; 253 254 sysi86(SI86V86, V86SC_IOPL, 0); 255 256 ExtendedEnabled = FALSE; 257#endif /* i386 */ 258} 259