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
60 static Bool useDevMem = FALSE;
61 static 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 */
71 static void
checkDevMem(Bool warn)72 checkDevMem(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
152 void
xf86OSInitVidMem(VidMemInfoPtr pVidMem)153 xf86OSInitVidMem(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
167 static Bool ExtendedEnabled = FALSE;
168
169 Bool
xf86EnableIO()170 xf86EnableIO()
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
190 void
xf86DisableIO()191 xf86DisableIO()
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 /***************************************************************************/
206 /* I/O Permissions section */
207 /***************************************************************************/
208
209 static Bool ExtendedEnabled = FALSE;
210
211 Bool
xf86EnableIO()212 xf86EnableIO()
213 {
214 if (ExtendedEnabled)
215 return TRUE;
216
217 if (amd64_iopl(TRUE) < 0) {
218 #ifndef __OpenBSD__
219 xf86Msg(X_WARNING, "%s: Failed to set IOPL for extended I/O",
220 "xf86EnableIO");
221 #else
222 xf86Msg(X_WARNING, "%s: Failed to set IOPL for extended I/O\n%s",
223 "xf86EnableIO", SYSCTL_MSG);
224 #endif
225 return FALSE;
226 }
227 ExtendedEnabled = TRUE;
228
229 return TRUE;
230 }
231
232 void
xf86DisableIO()233 xf86DisableIO()
234 {
235 if (!ExtendedEnabled)
236 return;
237
238 if (amd64_iopl(FALSE) == 0) {
239 ExtendedEnabled = FALSE;
240 }
241 /* Otherwise, the X server has revoqued its root uid,
242 and thus cannot give up IO privileges any more */
243
244 return;
245 }
246
247 #endif /* USE_AMD64_IOPL */
248
249 #ifdef USE_DEV_IO
250 static int IoFd = -1;
251
252 Bool
xf86EnableIO()253 xf86EnableIO()
254 {
255 if (IoFd >= 0)
256 return TRUE;
257
258 if ((IoFd = open("/dev/io", O_RDWR)) == -1) {
259 xf86Msg(X_WARNING, "xf86EnableIO: "
260 "Failed to open /dev/io for extended I/O");
261 return FALSE;
262 }
263 return TRUE;
264 }
265
266 void
xf86DisableIO()267 xf86DisableIO()
268 {
269 if (IoFd < 0)
270 return;
271
272 close(IoFd);
273 IoFd = -1;
274 return;
275 }
276
277 #endif
278
279 #ifdef __NetBSD__
280 /***************************************************************************/
281 /* Set TV output mode */
282 /***************************************************************************/
283 void
xf86SetTVOut(int mode)284 xf86SetTVOut(int mode)
285 {
286 switch (xf86Info.consType) {
287 #ifdef PCCONS_SUPPORT
288 case PCCONS:{
289
290 if (ioctl(xf86Info.consoleFd, CONSOLE_X_TV_ON, &mode) < 0) {
291 xf86Msg(X_WARNING,
292 "xf86SetTVOut: Could not set console to TV output, %s\n",
293 strerror(errno));
294 }
295 }
296 break;
297 #endif /* PCCONS_SUPPORT */
298
299 default:
300 FatalError("Xf86SetTVOut: Unsupported console");
301 break;
302 }
303 return;
304 }
305
306 void
xf86SetRGBOut()307 xf86SetRGBOut()
308 {
309 switch (xf86Info.consType) {
310 #ifdef PCCONS_SUPPORT
311 case PCCONS:{
312
313 if (ioctl(xf86Info.consoleFd, CONSOLE_X_TV_OFF, 0) < 0) {
314 xf86Msg(X_WARNING,
315 "xf86SetTVOut: Could not set console to RGB output, %s\n",
316 strerror(errno));
317 }
318 }
319 break;
320 #endif /* PCCONS_SUPPORT */
321
322 default:
323 FatalError("Xf86SetTVOut: Unsupported console");
324 break;
325 }
326 return;
327 }
328 #endif
329