1/* 2 * Copyright 1992 by Rich Murphey <Rich@Rice.edu> 3 * Copyright 1993 by David Wexelblat <dwex@goblin.org> 4 * 5 * Permission to use, copy, modify, distribute, and sell this software and its 6 * documentation for any purpose is hereby granted without fee, provided that 7 * the above copyright notice appear in all copies and that both that 8 * copyright notice and this permission notice appear in supporting 9 * documentation, and that the names of Rich Murphey and David Wexelblat 10 * not be used in advertising or publicity pertaining to distribution of 11 * the software without specific, written prior permission. Rich Murphey and 12 * David Wexelblat make no representations about the suitability of this 13 * software for any purpose. It is provided "as is" without express or 14 * implied warranty. 15 * 16 * RICH MURPHEY AND DAVID WEXELBLAT DISCLAIM ALL WARRANTIES WITH REGARD TO 17 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND 18 * FITNESS, IN NO EVENT SHALL RICH MURPHEY OR DAVID WEXELBLAT BE LIABLE FOR 19 * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER 20 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF 21 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN 22 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 23 * 24 */ 25 26#ifdef HAVE_XORG_CONFIG_H 27#include <xorg-config.h> 28#endif 29 30#include <X11/X.h> 31#include "xf86.h" 32#include "xf86Priv.h" 33 34#include <errno.h> 35#include <sys/mman.h> 36 37#include "xf86_OSlib.h" 38#include "xf86OSpriv.h" 39 40#if defined(__NetBSD__) && !defined(MAP_FILE) 41#define MAP_FLAGS MAP_SHARED 42#else 43#define MAP_FLAGS (MAP_FILE | MAP_SHARED) 44#endif 45 46#ifdef __OpenBSD__ 47#define SYSCTL_MSG "\tCheck that you have set 'machdep.allowaperture=1'\n"\ 48 "\tin /etc/sysctl.conf and reboot your machine\n" \ 49 "\trefer to xf86(4) for details" 50#define SYSCTL_MSG2 \ 51 "Check that you have set 'machdep.allowaperture=2'\n" \ 52 "\tin /etc/sysctl.conf and reboot your machine\n" \ 53 "\trefer to xf86(4) for details" 54#endif 55 56/***************************************************************************/ 57/* Video Memory Mapping section */ 58/***************************************************************************/ 59 60static Bool useDevMem = FALSE; 61static int devMemFd = -1; 62 63#ifdef HAS_APERTURE_DRV 64#define DEV_APERTURE "/dev/xf86" 65#endif 66 67/* 68 * Check if /dev/mem can be mmap'd. If it can't print a warning when 69 * "warn" is TRUE. 70 */ 71static void 72checkDevMem(Bool warn) 73{ 74 static Bool devMemChecked = FALSE; 75 int fd; 76 void *base; 77 78 if (devMemChecked) 79 return; 80 devMemChecked = TRUE; 81 82 if ((fd = open(DEV_MEM, O_RDWR)) >= 0) { 83 /* Try to map a page at the VGA address */ 84 base = mmap((caddr_t) 0, 4096, PROT_READ | PROT_WRITE, 85 MAP_FLAGS, fd, (off_t) 0xA0000); 86 87 if (base != MAP_FAILED) { 88 munmap((caddr_t) base, 4096); 89 devMemFd = fd; 90 useDevMem = TRUE; 91 return; 92 } 93 else { 94 /* This should not happen */ 95 if (warn) { 96 xf86Msg(X_WARNING, "checkDevMem: failed to mmap %s (%s)\n", 97 DEV_MEM, strerror(errno)); 98 } 99 useDevMem = FALSE; 100 return; 101 } 102 } 103#ifndef HAS_APERTURE_DRV 104 if (warn) { 105 xf86Msg(X_WARNING, "checkDevMem: failed to open %s (%s)\n", 106 DEV_MEM, strerror(errno)); 107 } 108 useDevMem = FALSE; 109 return; 110#else 111 /* Failed to open /dev/mem, try the aperture driver */ 112 if ((fd = open(DEV_APERTURE, O_RDWR)) >= 0) { 113 /* Try to map a page at the VGA address */ 114 base = mmap((caddr_t) 0, 4096, PROT_READ | PROT_WRITE, 115 MAP_FLAGS, fd, (off_t) 0xA0000); 116 117 if (base != MAP_FAILED) { 118 munmap((caddr_t) base, 4096); 119 devMemFd = fd; 120 useDevMem = TRUE; 121 xf86Msg(X_INFO, "checkDevMem: using aperture driver %s\n", 122 DEV_APERTURE); 123 return; 124 } 125 else { 126 127 if (warn) { 128 xf86Msg(X_WARNING, "checkDevMem: failed to mmap %s (%s)\n", 129 DEV_APERTURE, strerror(errno)); 130 } 131 } 132 } 133 else { 134 if (warn) { 135#ifndef __OpenBSD__ 136 xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n" 137 "\t(%s)\n", DEV_MEM, DEV_APERTURE, strerror(errno)); 138#else /* __OpenBSD__ */ 139 xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n" 140 "\t(%s)\n%s", DEV_MEM, DEV_APERTURE, strerror(errno), 141 SYSCTL_MSG); 142#endif /* __OpenBSD__ */ 143 } 144 } 145 146 useDevMem = FALSE; 147 return; 148 149#endif 150} 151 152void 153xf86OSInitVidMem(VidMemInfoPtr pVidMem) 154{ 155 checkDevMem(TRUE); 156 157 pci_system_init_dev_mem(devMemFd); 158 159 pVidMem->initialised = TRUE; 160} 161 162#ifdef USE_I386_IOPL 163/***************************************************************************/ 164/* I/O Permissions section */ 165/***************************************************************************/ 166 167static Bool ExtendedEnabled = FALSE; 168 169Bool 170xf86EnableIO() 171{ 172 if (ExtendedEnabled) 173 return TRUE; 174 175 if (i386_iopl(TRUE) < 0) { 176#ifndef __OpenBSD__ 177 xf86Msg(X_WARNING, "%s: Failed to set IOPL for extended I/O", 178 "xf86EnableIO"); 179#else 180 xf86Msg(X_WARNING, "%s: Failed to set IOPL for extended I/O\n%s", 181 "xf86EnableIO", SYSCTL_MSG); 182#endif 183 return FALSE; 184 } 185 ExtendedEnabled = TRUE; 186 187 return TRUE; 188} 189 190void 191xf86DisableIO() 192{ 193 if (!ExtendedEnabled) 194 return; 195 196 i386_iopl(FALSE); 197 ExtendedEnabled = FALSE; 198 199 return; 200} 201 202#endif /* USE_I386_IOPL */ 203 204#ifdef USE_AMD64_IOPL 205#ifdef __NetBSD__ 206#define amd64_iopl(x) x86_64_iopl(x) 207#endif 208/***************************************************************************/ 209/* I/O Permissions section */ 210/***************************************************************************/ 211 212static Bool ExtendedEnabled = FALSE; 213 214Bool 215xf86EnableIO() 216{ 217 if (ExtendedEnabled) 218 return TRUE; 219 220 if (amd64_iopl(TRUE) < 0) { 221#ifndef __OpenBSD__ 222 xf86Msg(X_WARNING, "%s: Failed to set IOPL for extended I/O", 223 "xf86EnableIO"); 224#else 225 xf86Msg(X_WARNING, "%s: Failed to set IOPL for extended I/O\n%s", 226 "xf86EnableIO", SYSCTL_MSG); 227#endif 228 return FALSE; 229 } 230 ExtendedEnabled = TRUE; 231 232 return TRUE; 233} 234 235void 236xf86DisableIO() 237{ 238 if (!ExtendedEnabled) 239 return; 240 241 if (amd64_iopl(FALSE) == 0) { 242 ExtendedEnabled = FALSE; 243 } 244 /* Otherwise, the X server has revoqued its root uid, 245 and thus cannot give up IO privileges any more */ 246 247 return; 248} 249 250#endif /* USE_AMD64_IOPL */ 251 252#ifdef USE_DEV_IO 253static int IoFd = -1; 254 255Bool 256xf86EnableIO() 257{ 258 if (IoFd >= 0) 259 return TRUE; 260 261 if ((IoFd = open("/dev/io", O_RDWR)) == -1) { 262 xf86Msg(X_WARNING, "xf86EnableIO: " 263 "Failed to open /dev/io for extended I/O"); 264 return FALSE; 265 } 266 return TRUE; 267} 268 269void 270xf86DisableIO() 271{ 272 if (IoFd < 0) 273 return; 274 275 close(IoFd); 276 IoFd = -1; 277 return; 278} 279 280#endif 281 282#ifdef __NetBSD__ 283/***************************************************************************/ 284/* Set TV output mode */ 285/***************************************************************************/ 286void 287xf86SetTVOut(int mode) 288{ 289 switch (xf86Info.consType) { 290#ifdef PCCONS_SUPPORT 291 case PCCONS:{ 292 293 if (ioctl(xf86Info.consoleFd, CONSOLE_X_TV_ON, &mode) < 0) { 294 xf86Msg(X_WARNING, 295 "xf86SetTVOut: Could not set console to TV output, %s\n", 296 strerror(errno)); 297 } 298 } 299 break; 300#endif /* PCCONS_SUPPORT */ 301 302 default: 303 FatalError("Xf86SetTVOut: Unsupported console"); 304 break; 305 } 306 return; 307} 308 309void 310xf86SetRGBOut() 311{ 312 switch (xf86Info.consType) { 313#ifdef PCCONS_SUPPORT 314 case PCCONS:{ 315 316 if (ioctl(xf86Info.consoleFd, CONSOLE_X_TV_OFF, 0) < 0) { 317 xf86Msg(X_WARNING, 318 "xf86SetTVOut: Could not set console to RGB output, %s\n", 319 strerror(errno)); 320 } 321 } 322 break; 323#endif /* PCCONS_SUPPORT */ 324 325 default: 326 FatalError("Xf86SetTVOut: Unsupported console"); 327 break; 328 } 329 return; 330} 331#endif 332