2 * Copyright 1992 by Rich Murphey <Rich@Rice.edu>
3 * Copyright 1993 by David Wexelblat <dwex@goblin.org>
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
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.
26 #ifdef HAVE_XORG_CONFIG_H
27 #include <xorg-config.h>
34 #include <sys/param.h>
36 #include <sys/sysctl.h>
38 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__NetBSD__)
39 #include <machine/sysarch.h>
44 #include "xf86_OSlib.h"
45 #include "xf86OSpriv.h"
47 #if defined(__NetBSD__) && !defined(MAP_FILE)
48 #define MAP_FLAGS MAP_SHARED
50 #define MAP_FLAGS (MAP_FILE | MAP_SHARED)
53 axpDevice
bsdGetAXP(void);
56 extern unsigned long dense_base(void);
58 static int axpSystem
= -1;
59 static unsigned long hae_thresh
;
60 static unsigned long hae_mask
;
65 static unsigned long base
= 0;
68 size_t len
= sizeof(base
);
76 mib
[2] = CPU_CHIPSET_MEM
;
78 if ((error
= sysctl(mib
, 3, &base
, &len
, NULL
, 0)) < 0)
80 if ((error
= sysctlbyname("hw.chipset.memory", &base
, &len
, 0, 0)) < 0)
82 FatalError("xf86MapVidMem: can't find memory\n");
92 size_t len
= sizeof(bwx
);
100 mib
[2] = CPU_CHIPSET_BWX
;
102 if ((error
= sysctl(mib
, 3, &bwx
, &len
, NULL
, 0)) < 0)
107 if ((error
= sysctlbyname("hw.chipset.bwx", &bwx
, &len
, 0, 0)) < 0)
113 #else /* __NetBSD__ */
114 static unsigned long hae_thresh
= (1UL << 24);
115 static unsigned long hae_mask
= 0xf8000000UL
; /* XXX - should use xf86AXP.c */
116 static struct alpha_bus_window
*abw
;
117 static int abw_count
= -1;
123 abw_count
= alpha_bus_getwindows(ALPHA_BUS_TYPE_PCI_MEM
, &abw
);
125 FatalError("init_abw: alpha_bus_getwindows failed\n");
135 xf86Msg(X_INFO
, "has_bwx = %d\n", abw
[0].abw_abst
.abst_flags
& ABST_BWX
? 1 : 0); /* XXXX */
136 return abw
[0].abw_abst
.abst_flags
& ABST_BWX
;
145 /* XXX check abst_flags for ABST_DENSE just to be safe? */
146 xf86Msg(X_INFO
, "dense base = %#lx\n", abw
[0].abw_abst
.abst_sys_start
); /* XXXX */
147 return abw
[0].abw_abst
.abst_sys_start
;
157 xf86Msg(X_INFO
, "memory base = %#lx\n", abw
[1].abw_abst
.abst_sys_start
); /* XXXX */
158 return abw
[1].abw_abst
.abst_sys_start
;
160 else if (abw_count
== 1) {
161 /* assume memory_base == dense_base */
162 xf86Msg(X_INFO
, "memory base = %#lx\n", abw
[0].abw_abst
.abst_sys_start
); /* XXXX */
163 return abw
[0].abw_abst
.abst_sys_start
;
166 xf86Msg(X_INFO
, "no memory base\n"); /* XXXX */
170 #endif /* __NetBSD__ */
172 #define BUS_BASE dense_base()
173 #define BUS_BASE_BWX memory_base()
175 /***************************************************************************/
176 /* Video Memory Mapping section */
177 /***************************************************************************/
180 #define SYSCTL_MSG "\tCheck that you have set 'machdep.allowaperture=1'\n"\
181 "\tin /etc/sysctl.conf and reboot your machine\n" \
182 "\trefer to xf86(4) for details"
185 static Bool useDevMem
= FALSE
;
186 static int devMemFd
= -1;
188 #ifdef HAS_APERTURE_DRV
189 #define DEV_APERTURE "/dev/xf86"
192 static pointer
mapVidMem(int, unsigned long, unsigned long, int);
193 static void unmapVidMem(int, pointer
, unsigned long);
194 static pointer
mapVidMemSparse(int, unsigned long, unsigned long, int);
195 static void unmapVidMemSparse(int, pointer
, unsigned long);
198 * Check if /dev/mem can be mmap'd. If it can't print a warning when
202 checkDevMem(Bool warn
)
204 static Bool devMemChecked
= FALSE
;
210 devMemChecked
= TRUE
;
212 #ifdef HAS_APERTURE_DRV
213 /* Try the aperture driver first */
214 if ((fd
= open(DEV_APERTURE
, O_RDWR
)) >= 0) {
215 /* Try to map a page at the VGA address */
216 base
= mmap((caddr_t
) 0, 4096, PROT_READ
| PROT_WRITE
,
217 MAP_FLAGS
, fd
, (off_t
) 0xA0000 + BUS_BASE
);
219 if (base
!= MAP_FAILED
) {
220 munmap((caddr_t
) base
, 4096);
223 xf86Msg(X_INFO
, "checkDevMem: using aperture driver %s\n",
229 xf86Msg(X_WARNING
, "checkDevMem: failed to mmap %s (%s)\n",
230 DEV_APERTURE
, strerror(errno
));
235 if ((fd
= open(DEV_MEM
, O_RDWR
)) >= 0) {
236 /* Try to map a page at the VGA address */
237 base
= mmap((caddr_t
) 0, 4096, PROT_READ
| PROT_WRITE
,
238 MAP_FLAGS
, fd
, (off_t
) 0xA0000 + BUS_BASE
);
240 if (base
!= MAP_FAILED
) {
241 munmap((caddr_t
) base
, 4096);
248 xf86Msg(X_WARNING
, "checkDevMem: failed to mmap %s (%s)\n",
249 DEV_MEM
, strerror(errno
));
254 #ifndef HAS_APERTURE_DRV
255 xf86Msg(X_WARNING
, "checkDevMem: failed to open/mmap %s (%s)\n",
256 DEV_MEM
, strerror(errno
));
259 xf86Msg(X_WARNING
, "checkDevMem: failed to open %s and %s\n"
260 "\t(%s)\n", DEV_APERTURE
, DEV_MEM
, strerror(errno
));
261 #else /* __OpenBSD__ */
262 xf86Msg(X_WARNING
, "checkDevMem: failed to open %s and %s\n"
263 "\t(%s)\n%s", DEV_APERTURE
, DEV_MEM
, strerror(errno
),
265 #endif /* __OpenBSD__ */
267 xf86ErrorF("\tlinear framebuffer access unavailable\n");
274 xf86OSInitVidMem(VidMemInfoPtr pVidMem
)
277 pVidMem
->linearSupported
= useDevMem
;
280 xf86Msg(X_PROBED
, "Machine type has 8/16 bit access\n");
281 pVidMem
->mapMem
= mapVidMem
;
282 pVidMem
->unmapMem
= unmapVidMem
;
285 xf86Msg(X_PROBED
, "Machine needs sparse mapping\n");
286 pVidMem
->mapMem
= mapVidMemSparse
;
287 pVidMem
->unmapMem
= unmapVidMemSparse
;
290 axpSystem
= bsdGetAXP();
291 hae_thresh
= xf86AXPParams
[axpSystem
].hae_thresh
;
292 hae_mask
= xf86AXPParams
[axpSystem
].hae_mask
;
293 #endif /* __NetBSD__ */
295 pVidMem
->initialised
= TRUE
;
299 mapVidMem(int ScreenNum
, unsigned long Base
, unsigned long Size
, int flags
)
304 Base
= Base
& ((1L << 32) - 1);
308 FatalError("xf86MapVidMem: failed to open %s (%s)\n",
309 DEV_MEM
, strerror(errno
));
311 base
= mmap((caddr_t
) 0, Size
,
312 (flags
& VIDMEM_READONLY
) ?
313 PROT_READ
: (PROT_READ
| PROT_WRITE
),
314 MAP_FLAGS
, devMemFd
, (off_t
) Base
+ BUS_BASE_BWX
);
315 if (base
== MAP_FAILED
) {
316 FatalError("%s: could not mmap %s [s=%lx,a=%lx] (%s)\n",
317 "xf86MapVidMem", DEV_MEM
, Size
, Base
, strerror(errno
));
322 /* else, mmap /dev/vga */
323 if ((unsigned long) Base
< 0xA0000 || (unsigned long) Base
>= 0xC0000) {
324 FatalError("%s: Address 0x%lx outside allowable range\n",
325 "xf86MapVidMem", Base
);
328 (flags
& VIDMEM_READONLY
) ?
329 PROT_READ
: (PROT_READ
| PROT_WRITE
),
330 MAP_FLAGS
, xf86Info
.consoleFd
, (unsigned long) Base
+ BUS_BASE
);
331 if (base
== MAP_FAILED
) {
332 FatalError("xf86MapVidMem: Could not mmap /dev/vga (%s)\n",
339 unmapVidMem(int ScreenNum
, pointer Base
, unsigned long Size
)
341 munmap((caddr_t
) Base
, Size
);
345 * Read BIOS via mmap()ing DEV_MEM
349 xf86ReadBIOS(unsigned long Base
, unsigned long Offset
, unsigned char *Buf
,
357 if (devMemFd
== -1) {
361 psize
= getpagesize();
362 Offset
+= Base
& (psize
- 1);
363 Base
&= ~(psize
- 1);
364 mlen
= (Offset
+ Len
+ psize
- 1) & ~(psize
- 1);
365 ptr
= (unsigned char *) mmap((caddr_t
) 0, mlen
, PROT_READ
,
366 MAP_SHARED
, devMemFd
, (off_t
) Base
+ BUS_BASE
);
367 if ((long) ptr
== -1) {
369 "xf86ReadBIOS: %s mmap[s=%x,a=%lx,o=%lx] failed (%s)\n",
370 DEV_MEM
, Len
, Base
, Offset
, strerror(errno
));
374 xf86MsgVerb(X_INFO
, 3,
375 "xf86ReadBIOS: BIOS at 0x%08x has signature 0x%04x\n", Base
,
376 ptr
[0] | (ptr
[1] << 8));
378 (void) memcpy(Buf
, (void *) (ptr
+ Offset
), Len
);
379 (void) munmap((caddr_t
) ptr
, mlen
);
381 xf86MsgVerb(X_INFO
, 3, "xf86ReadBIOS(%x, %x, Buf, %x)"
382 "-> %02x %02x %02x %02x...\n",
383 Base
, Offset
, Len
, Buf
[0], Buf
[1], Buf
[2], Buf
[3]);
388 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
390 extern int ioperm(unsigned long from
, unsigned long num
, int on
);
395 if (!ioperm(0, 65536, TRUE
))
406 #endif /* __FreeBSD_kernel__ || __OpenBSD__ */
413 alpha_pci_io_enable(1);
420 alpha_pci_io_enable(0);
423 #endif /* USE_ALPHA_PIO */
425 #define vuip volatile unsigned int *
427 static pointer memSBase
= 0;
428 static pointer memBase
= 0;
430 extern int readDense8(pointer Base
, register unsigned long Offset
);
431 extern int readDense16(pointer Base
, register unsigned long Offset
);
432 extern int readDense32(pointer Base
, register unsigned long Offset
);
434 writeDenseNB8(int Value
, pointer Base
, register unsigned long Offset
);
436 writeDenseNB16(int Value
, pointer Base
, register unsigned long Offset
);
438 writeDenseNB32(int Value
, pointer Base
, register unsigned long Offset
);
440 writeDense8(int Value
, pointer Base
, register unsigned long Offset
);
442 writeDense16(int Value
, pointer Base
, register unsigned long Offset
);
444 writeDense32(int Value
, pointer Base
, register unsigned long Offset
);
446 static int readSparse8(pointer Base
, register unsigned long Offset
);
447 static int readSparse16(pointer Base
, register unsigned long Offset
);
448 static int readSparse32(pointer Base
, register unsigned long Offset
);
450 writeSparseNB8(int Value
, pointer Base
, register unsigned long Offset
);
452 writeSparseNB16(int Value
, pointer Base
, register unsigned long Offset
);
454 writeSparseNB32(int Value
, pointer Base
, register unsigned long Offset
);
456 writeSparse8(int Value
, pointer Base
, register unsigned long Offset
);
458 writeSparse16(int Value
, pointer Base
, register unsigned long Offset
);
460 writeSparse32(int Value
, pointer Base
, register unsigned long Offset
);
462 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
463 extern int sysarch(int, void *);
470 sethae(u_int64_t hae
)
473 #define ALPHA_SETHAE 0
475 static struct parms p
;
479 sysarch(ALPHA_SETHAE
, (char *) &p
);
485 mapVidMemSparse(int ScreenNum
, unsigned long Base
, unsigned long Size
,
488 static Bool was_here
= FALSE
;
495 xf86WriteMmio8
= writeSparse8
;
496 xf86WriteMmio16
= writeSparse16
;
497 xf86WriteMmio32
= writeSparse32
;
498 xf86WriteMmioNB8
= writeSparseNB8
;
499 xf86WriteMmioNB16
= writeSparseNB16
;
500 xf86WriteMmioNB32
= writeSparseNB32
;
501 xf86ReadMmio8
= readSparse8
;
502 xf86ReadMmio16
= readSparse16
;
503 xf86ReadMmio32
= readSparse32
;
505 memBase
= mmap((caddr_t
) 0, 0x100000000,
506 PROT_READ
| PROT_WRITE
,
507 MAP_SHARED
, devMemFd
, (off_t
) BUS_BASE
);
508 memSBase
= mmap((caddr_t
) 0, 0x100000000,
509 PROT_READ
| PROT_WRITE
,
510 MAP_SHARED
, devMemFd
, (off_t
) BUS_BASE_BWX
);
512 if (memSBase
== MAP_FAILED
|| memBase
== MAP_FAILED
) {
513 FatalError("xf86MapVidMem: Could not mmap framebuffer (%s)\n",
517 return (pointer
) ((unsigned long) memBase
+ Base
);
521 unmapVidMemSparse(int ScreenNum
, pointer Base
, unsigned long Size
)
526 readSparse8(pointer Base
, register unsigned long Offset
)
528 register unsigned long result
, shift
;
529 register unsigned long msb
;
532 Offset
+= (unsigned long) Base
- (unsigned long) memBase
;
533 shift
= (Offset
& 0x3) << 3;
534 if (Offset
>= (hae_thresh
)) {
535 msb
= Offset
& hae_mask
;
537 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
541 result
= *(vuip
) ((unsigned long) memSBase
+ (Offset
<< 5));
543 return 0xffUL
& result
;
547 readSparse16(pointer Base
, register unsigned long Offset
)
549 register unsigned long result
, shift
;
550 register unsigned long msb
;
553 Offset
+= (unsigned long) Base
- (unsigned long) memBase
;
554 shift
= (Offset
& 0x2) << 3;
555 if (Offset
>= (hae_thresh
)) {
556 msb
= Offset
& hae_mask
;
558 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
563 *(vuip
) ((unsigned long) memSBase
+ (Offset
<< 5) + (1 << (5 - 2)));
565 return 0xffffUL
& result
;
569 readSparse32(pointer Base
, register unsigned long Offset
)
572 return *(vuip
) ((unsigned long) Base
+ (Offset
));
576 writeSparse8(int Value
, pointer Base
, register unsigned long Offset
)
578 register unsigned long msb
;
579 register unsigned int b
= Value
& 0xffU
;
582 Offset
+= (unsigned long) Base
- (unsigned long) memBase
;
583 if (Offset
>= (hae_thresh
)) {
584 msb
= Offset
& hae_mask
;
586 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
590 *(vuip
) ((unsigned long) memSBase
+ (Offset
<< 5)) = b
* 0x01010101;
594 writeSparse16(int Value
, pointer Base
, register unsigned long Offset
)
596 register unsigned long msb
;
597 register unsigned int w
= Value
& 0xffffU
;
600 Offset
+= (unsigned long) Base
- (unsigned long) memBase
;
601 if (Offset
>= (hae_thresh
)) {
602 msb
= Offset
& hae_mask
;
604 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
608 *(vuip
) ((unsigned long) memSBase
+ (Offset
<< 5) + (1 << (5 - 2))) =
614 writeSparse32(int Value
, pointer Base
, register unsigned long Offset
)
617 *(vuip
) ((unsigned long) Base
+ (Offset
)) = Value
;
622 writeSparseNB8(int Value
, pointer Base
, register unsigned long Offset
)
624 register unsigned long msb
;
625 register unsigned int b
= Value
& 0xffU
;
627 Offset
+= (unsigned long) Base
- (unsigned long) memBase
;
628 if (Offset
>= (hae_thresh
)) {
629 msb
= Offset
& hae_mask
;
631 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
635 *(vuip
) ((unsigned long) memSBase
+ (Offset
<< 5)) = b
* 0x01010101;
639 writeSparseNB16(int Value
, pointer Base
, register unsigned long Offset
)
641 register unsigned long msb
;
642 register unsigned int w
= Value
& 0xffffU
;
644 Offset
+= (unsigned long) Base
- (unsigned long) memBase
;
645 if (Offset
>= (hae_thresh
)) {
646 msb
= Offset
& hae_mask
;
648 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
652 *(vuip
) ((unsigned long) memSBase
+ (Offset
<< 5) + (1 << (5 - 2))) =
657 writeSparseNB32(int Value
, pointer Base
, register unsigned long Offset
)
659 *(vuip
) ((unsigned long) Base
+ (Offset
)) = Value
;
663 void (*xf86WriteMmio8
) (int Value
, pointer Base
, unsigned long Offset
)
665 void (*xf86WriteMmio16
) (int Value
, pointer Base
, unsigned long Offset
)
667 void (*xf86WriteMmio32
) (int Value
, pointer Base
, unsigned long Offset
)
669 void (*xf86WriteMmioNB8
) (int Value
, pointer Base
, unsigned long Offset
)
671 void (*xf86WriteMmioNB16
) (int Value
, pointer Base
, unsigned long Offset
)
673 void (*xf86WriteMmioNB32
) (int Value
, pointer Base
, unsigned long Offset
)
675 int (*xf86ReadMmio8
) (pointer Base
, unsigned long Offset
)
677 int (*xf86ReadMmio16
) (pointer Base
, unsigned long Offset
)
679 int (*xf86ReadMmio32
) (pointer Base
, unsigned long Offset
)