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 <sys/param.h>
35 #ifndef __NetBSD__
36 #include <sys/sysctl.h>
37 #endif
38 
39 #include "xf86_OSlib.h"
40 #include "xf86OSpriv.h"
41 
42 #if defined(__NetBSD__) && !defined(MAP_FILE)
43 #define MAP_FLAGS MAP_SHARED
44 #else
45 #define MAP_FLAGS (MAP_FILE | MAP_SHARED)
46 #endif
47 
48 #ifndef __NetBSD__
49 extern unsigned long dense_base(void);
50 #else                           /* __NetBSD__ */
51 static struct alpha_bus_window *abw;
52 static int abw_count = -1;
53 
54 static void
init_abw(void)55 init_abw(void)
56 {
57     if (abw_count < 0) {
58         abw_count = alpha_bus_getwindows(ALPHA_BUS_TYPE_PCI_MEM, &abw);
59         if (abw_count <= 0)
60             FatalError("init_abw: alpha_bus_getwindows failed\n");
61     }
62 }
63 
64 static unsigned long
dense_base(void)65 dense_base(void)
66 {
67     if (abw_count < 0)
68         init_abw();
69 
70     /* XXX check abst_flags for ABST_DENSE just to be safe? */
71     xf86Msg(X_INFO, "dense base = %#lx\n", abw[0].abw_abst.abst_sys_start);     /* XXXX */
72     return abw[0].abw_abst.abst_sys_start;
73 }
74 
75 #endif                          /* __NetBSD__ */
76 
77 #define BUS_BASE	dense_base()
78 
79 /***************************************************************************/
80 /* Video Memory Mapping section                                            */
81 /***************************************************************************/
82 
83 #ifdef __OpenBSD__
84 #define SYSCTL_MSG "\tCheck that you have set 'machdep.allowaperture=1'\n"\
85                   "\tin /etc/sysctl.conf and reboot your machine\n" \
86                   "\trefer to xf86(4) for details"
87 #endif
88 
89 static int devMemFd = -1;
90 
91 #ifdef HAS_APERTURE_DRV
92 #define DEV_APERTURE "/dev/xf86"
93 #endif
94 
95 /*
96  * Check if /dev/mem can be mmap'd.  If it can't print a warning when
97  * "warn" is TRUE.
98  */
99 static void
checkDevMem(Bool warn)100 checkDevMem(Bool warn)
101 {
102     static Bool devMemChecked = FALSE;
103     int fd;
104     void *base;
105 
106     if (devMemChecked)
107         return;
108     devMemChecked = TRUE;
109 
110 #ifdef HAS_APERTURE_DRV
111     /* Try the aperture driver first */
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 + BUS_BASE);
116 
117         if (base != MAP_FAILED) {
118             munmap((caddr_t) base, 4096);
119             devMemFd = fd;
120             xf86Msg(X_INFO, "checkDevMem: using aperture driver %s\n",
121                     DEV_APERTURE);
122             return;
123         }
124         else {
125             if (warn) {
126                 xf86Msg(X_WARNING, "checkDevMem: failed to mmap %s (%s)\n",
127                         DEV_APERTURE, strerror(errno));
128             }
129         }
130     }
131 #endif
132     if ((fd = open(DEV_MEM, O_RDWR)) >= 0) {
133         /* Try to map a page at the VGA address */
134         base = mmap((caddr_t) 0, 4096, PROT_READ | PROT_WRITE,
135                     MAP_FLAGS, fd, (off_t) 0xA0000 + BUS_BASE);
136 
137         if (base != MAP_FAILED) {
138             munmap((caddr_t) base, 4096);
139             devMemFd = fd;
140             return;
141         }
142         else {
143             if (warn) {
144                 xf86Msg(X_WARNING, "checkDevMem: failed to mmap %s (%s)\n",
145                         DEV_MEM, strerror(errno));
146             }
147         }
148     }
149     if (warn) {
150 #ifndef HAS_APERTURE_DRV
151         xf86Msg(X_WARNING, "checkDevMem: failed to open/mmap %s (%s)\n",
152                 DEV_MEM, strerror(errno));
153 #else
154 #ifndef __OpenBSD__
155         xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n"
156                 "\t(%s)\n", DEV_APERTURE, DEV_MEM, strerror(errno));
157 #else                           /* __OpenBSD__ */
158         xf86Msg(X_WARNING, "checkDevMem: failed to open %s and %s\n"
159                 "\t(%s)\n%s", DEV_APERTURE, DEV_MEM, strerror(errno),
160                 SYSCTL_MSG);
161 #endif                          /* __OpenBSD__ */
162 #endif
163         xf86ErrorF("\tlinear framebuffer access unavailable\n");
164     }
165     return;
166 }
167 
168 void
xf86OSInitVidMem(VidMemInfoPtr pVidMem)169 xf86OSInitVidMem(VidMemInfoPtr pVidMem)
170 {
171     checkDevMem(TRUE);
172 
173     pVidMem->initialised = TRUE;
174 }
175 
176 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
177 
178 extern int ioperm(unsigned long from, unsigned long num, int on);
179 
180 Bool
xf86EnableIO()181 xf86EnableIO()
182 {
183     if (!ioperm(0, 65536, TRUE))
184         return TRUE;
185     return FALSE;
186 }
187 
188 void
xf86DisableIO()189 xf86DisableIO()
190 {
191     return;
192 }
193 
194 #endif                          /* __FreeBSD_kernel__ || __OpenBSD__ */
195 
196 #ifdef USE_ALPHA_PIO
197 
198 Bool
xf86EnableIO()199 xf86EnableIO()
200 {
201     alpha_pci_io_enable(1);
202     return TRUE;
203 }
204 
205 void
xf86DisableIO()206 xf86DisableIO()
207 {
208     alpha_pci_io_enable(0);
209 }
210 
211 #endif                          /* USE_ALPHA_PIO */
212 
213 extern int readDense8(void *Base, register unsigned long Offset);
214 extern int readDense16(void *Base, register unsigned long Offset);
215 extern int readDense32(void *Base, register unsigned long Offset);
216 extern void
217  writeDense8(int Value, void *Base, register unsigned long Offset);
218 extern void
219  writeDense16(int Value, void *Base, register unsigned long Offset);
220 extern void
221  writeDense32(int Value, void *Base, register unsigned long Offset);
222 
223 void (*xf86WriteMmio8) (int Value, void *Base, unsigned long Offset)
224     = writeDense8;
225 void (*xf86WriteMmio16) (int Value, void *Base, unsigned long Offset)
226     = writeDense16;
227 void (*xf86WriteMmio32) (int Value, void *Base, unsigned long Offset)
228     = writeDense32;
229 int (*xf86ReadMmio8) (void *Base, unsigned long Offset)
230     = readDense8;
231 int (*xf86ReadMmio16) (void *Base, unsigned long Offset)
232     = readDense16;
233 int (*xf86ReadMmio32) (void *Base, unsigned long Offset)
234     = readDense32;
235