Commit | Line | Data |
---|---|---|
a09e091a JB |
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 | ||
66 | static char *apertureDevName = NULL; | |
67 | static int apertureDevFD_ro = -1; | |
68 | static int apertureDevFD_rw = -1; | |
69 | ||
70 | static Bool | |
71 | solOpenAperture(void) | |
72 | { | |
73 | if (apertureDevName == NULL) { | |
74 | apertureDevName = "/dev/xsvc"; | |
75 | if ((apertureDevFD_rw = open(apertureDevName, O_RDWR)) < 0) { | |
76 | xf86MsgVerb(X_WARNING, 0, | |
77 | "solOpenAperture: failed to open %s (%s)\n", | |
78 | apertureDevName, strerror(errno)); | |
79 | apertureDevName = "/dev/fbs/aperture"; | |
80 | apertureDevFD_rw = open(apertureDevName, O_RDWR); | |
81 | } | |
82 | apertureDevFD_ro = open(apertureDevName, O_RDONLY); | |
83 | ||
84 | if ((apertureDevFD_rw < 0) || (apertureDevFD_ro < 0)) { | |
85 | xf86MsgVerb(X_WARNING, 0, | |
86 | "solOpenAperture: failed to open %s (%s)\n", | |
87 | apertureDevName, strerror(errno)); | |
88 | xf86MsgVerb(X_WARNING, 0, | |
89 | "solOpenAperture: either /dev/fbs/aperture" | |
90 | " or /dev/xsvc required\n"); | |
91 | ||
92 | apertureDevName = NULL; | |
93 | ||
94 | if (apertureDevFD_rw >= 0) { | |
95 | close(apertureDevFD_rw); | |
96 | } | |
97 | apertureDevFD_rw = -1; | |
98 | ||
99 | if (apertureDevFD_ro >= 0) { | |
100 | close(apertureDevFD_ro); | |
101 | } | |
102 | apertureDevFD_ro = -1; | |
103 | ||
104 | return FALSE; | |
105 | } | |
106 | } | |
107 | return TRUE; | |
108 | } | |
109 | ||
110 | static pointer | |
111 | solMapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int Flags) | |
112 | { | |
113 | pointer base; | |
114 | int fd; | |
115 | int prot; | |
116 | ||
117 | if (Flags & VIDMEM_READONLY) { | |
118 | fd = apertureDevFD_ro; | |
119 | prot = PROT_READ; | |
120 | } | |
121 | else { | |
122 | fd = apertureDevFD_rw; | |
123 | prot = PROT_READ | PROT_WRITE; | |
124 | } | |
125 | ||
126 | if (fd < 0) { | |
127 | xf86DrvMsg(ScreenNum, X_ERROR, | |
128 | "solMapVidMem: failed to open %s (%s)\n", | |
129 | apertureDevName, strerror(errno)); | |
130 | return NULL; | |
131 | } | |
132 | ||
133 | base = mmap(NULL, Size, prot, MAP_SHARED, fd, (off_t) Base); | |
134 | ||
135 | if (base == MAP_FAILED) { | |
136 | xf86DrvMsg(ScreenNum, X_ERROR, | |
137 | "solMapVidMem: failed to mmap %s (0x%08lx,0x%lx) (%s)\n", | |
138 | apertureDevName, Base, Size, strerror(errno)); | |
139 | return NULL; | |
140 | } | |
141 | ||
142 | return base; | |
143 | } | |
144 | ||
145 | /* ARGSUSED */ | |
146 | static void | |
147 | solUnMapVidMem(int ScreenNum, pointer Base, unsigned long Size) | |
148 | { | |
149 | if (munmap(Base, Size) != 0) { | |
150 | xf86DrvMsgVerb(ScreenNum, X_WARNING, 0, | |
151 | "solUnMapVidMem: failed to unmap %s" | |
152 | " (0x%p,0x%lx) (%s)\n", | |
153 | apertureDevName, Base, Size, strerror(errno)); | |
154 | } | |
155 | } | |
156 | ||
157 | _X_HIDDEN void | |
158 | xf86OSInitVidMem(VidMemInfoPtr pVidMem) | |
159 | { | |
160 | pVidMem->linearSupported = solOpenAperture(); | |
161 | if (pVidMem->linearSupported) { | |
162 | pVidMem->mapMem = solMapVidMem; | |
163 | pVidMem->unmapMem = solUnMapVidMem; | |
164 | } | |
165 | else { | |
166 | xf86MsgVerb(X_WARNING, 0, | |
167 | "xf86OSInitVidMem: linear memory access disabled\n"); | |
168 | } | |
169 | pVidMem->initialised = TRUE; | |
170 | } | |
171 | ||
172 | /* | |
173 | * Read BIOS via mmap()ing physical memory. | |
174 | */ | |
175 | int | |
176 | xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf, | |
177 | int Len) | |
178 | { | |
179 | unsigned char *ptr; | |
180 | int psize; | |
181 | int mlen; | |
182 | ||
183 | psize = getpagesize(); | |
184 | Offset += Base & (psize - 1); | |
185 | Base &= ~(psize - 1); | |
186 | mlen = (Offset + Len + psize - 1) & ~(psize - 1); | |
187 | ||
188 | if (solOpenAperture() == FALSE) { | |
189 | xf86Msg(X_WARNING, | |
190 | "xf86ReadBIOS: Failed to open aperture to read BIOS\n"); | |
191 | return -1; | |
192 | } | |
193 | ||
194 | ptr = (unsigned char *) mmap(NULL, mlen, PROT_READ, | |
195 | MAP_SHARED, apertureDevFD_ro, (off_t) Base); | |
196 | if (ptr == MAP_FAILED) { | |
197 | xf86Msg(X_WARNING, "xf86ReadBIOS: %s mmap failed [0x%08lx, 0x%04x]\n", | |
198 | apertureDevName, Base, mlen); | |
199 | return -1; | |
200 | } | |
201 | ||
202 | (void) memcpy(Buf, (void *) (ptr + Offset), Len); | |
203 | if (munmap((caddr_t) ptr, mlen) != 0) { | |
204 | xf86MsgVerb(X_WARNING, 0, | |
205 | "xf86ReadBIOS: failed to unmap %s (0x%p,0x%x) (%s)\n", | |
206 | apertureDevName, ptr, mlen, strerror(errno)); | |
207 | } | |
208 | ||
209 | return Len; | |
210 | } | |
211 | ||
212 | /***************************************************************************/ | |
213 | /* I/O Permissions section */ | |
214 | /***************************************************************************/ | |
215 | ||
216 | #if defined(__i386__) || defined(__i386) || defined(__x86) | |
217 | static Bool ExtendedEnabled = FALSE; | |
218 | #endif | |
219 | ||
220 | Bool | |
221 | xf86EnableIO(void) | |
222 | { | |
223 | #if defined(__i386__) || defined(__i386) || defined(__x86) | |
224 | if (ExtendedEnabled) | |
225 | return TRUE; | |
226 | ||
227 | if (sysi86(SI86V86, V86SC_IOPL, PS_IOPL) < 0) { | |
228 | xf86Msg(X_WARNING, "xf86EnableIOPorts: Failed to set IOPL for I/O\n"); | |
229 | return FALSE; | |
230 | } | |
231 | ExtendedEnabled = TRUE; | |
232 | #endif /* i386 */ | |
233 | return TRUE; | |
234 | } | |
235 | ||
236 | void | |
237 | xf86DisableIO(void) | |
238 | { | |
239 | #if defined(__i386__) || defined(__i386) || defined(__x86) | |
240 | if (!ExtendedEnabled) | |
241 | return; | |
242 | ||
243 | sysi86(SI86V86, V86SC_IOPL, 0); | |
244 | ||
245 | ExtendedEnabled = FALSE; | |
246 | #endif /* i386 */ | |
247 | } |