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>
37 # if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
38 # include <machine/sysarch.h>
41 # include <machine/sysarch.h>
46 #include "xf86_OSlib.h"
47 #include "xf86OSpriv.h"
49 #if defined(__NetBSD__) && !defined(MAP_FILE)
50 #define MAP_FLAGS MAP_SHARED
52 #define MAP_FLAGS (MAP_FILE | MAP_SHARED)
56 #define MAP_FAILED ((caddr_t)-1)
59 axpDevice
bsdGetAXP(void);
62 extern unsigned long dense_base(void);
64 static int axpSystem
= -1;
65 static unsigned long hae_thresh
;
66 static unsigned long hae_mask
;
67 static unsigned long bus_base
;
68 static unsigned long sparse_size
;
73 static unsigned long base
= 0;
76 size_t len
= sizeof(base
);
83 mib
[2] = CPU_CHIPSET_MEM
;
85 if ((error
= sysctl(mib
, 3, &base
, &len
, NULL
, 0)) < 0)
87 if ((error
= sysctlbyname("hw.chipset.memory", &base
, &len
,
90 FatalError("xf86MapVidMem: can't find memory\n");
100 size_t len
= sizeof(bwx
);
105 mib
[0] = CTL_MACHDEP
;
106 mib
[1] = CPU_CHIPSET
;
107 mib
[2] = CPU_CHIPSET_BWX
;
109 if ((error
= sysctl(mib
, 3, &bwx
, &len
, NULL
, 0)) < 0)
114 if ((error
= sysctlbyname("hw.chipset.bwx", &bwx
, &len
, 0, 0)) < 0)
120 #else /* __NetBSD__ */
121 static unsigned long hae_thresh
= (1UL << 24);
122 static unsigned long hae_mask
= 0xf8000000UL
; /* XXX - should use xf86AXP.c */
123 static struct alpha_bus_window
*abw
;
124 static int abw_count
= -1;
130 abw_count
= alpha_bus_getwindows(ALPHA_BUS_TYPE_PCI_MEM
, &abw
);
132 FatalError("init_abw: alpha_bus_getwindows failed\n");
142 xf86Msg(X_INFO
, "has_bwx = %d\n",
143 abw
[0].abw_abst
.abst_flags
& ABST_BWX
? 1 : 0); /* XXXX */
144 return abw
[0].abw_abst
.abst_flags
& ABST_BWX
;
153 /* XXX check abst_flags for ABST_DENSE just to be safe? */
154 xf86Msg(X_INFO
, "dense base = %#lx\n",
155 abw
[0].abw_abst
.abst_sys_start
); /* XXXX */
156 return abw
[0].abw_abst
.abst_sys_start
;
166 xf86Msg(X_INFO
, "memory base = %#lx\n",
167 abw
[1].abw_abst
.abst_sys_start
); /* XXXX */
168 return abw
[1].abw_abst
.abst_sys_start
;
170 xf86Msg(X_INFO
, "no memory base\n"); /* XXXX */
174 #endif /* __NetBSD__ */
176 #define BUS_BASE dense_base()
177 #define BUS_BASE_BWX memory_base()
179 /***************************************************************************/
180 /* Video Memory Mapping section */
181 /***************************************************************************/
184 #define SYSCTL_MSG "\tCheck that you have set 'machdep.allowaperture=1'\n"\
185 "\tin /etc/sysctl.conf and reboot your machine\n" \
186 "\trefer to xf86(4) for details"
189 static Bool useDevMem
= FALSE
;
190 static int devMemFd
= -1;
192 #ifdef HAS_APERTURE_DRV
193 #define DEV_APERTURE "/dev/xf86"
195 #define DEV_MEM "/dev/mem"
197 static pointer
mapVidMem(int, unsigned long, unsigned long, int);
198 static void unmapVidMem(int, pointer
, unsigned long);
199 static pointer
mapVidMemSparse(int, unsigned long, unsigned long, int);
200 static void unmapVidMemSparse(int, pointer
, unsigned long);
203 * Check if /dev/mem can be mmap'd. If it can't print a warning when
207 checkDevMem(Bool warn
)
209 static Bool devMemChecked
= FALSE
;
215 devMemChecked
= TRUE
;
217 #ifdef HAS_APERTURE_DRV
218 /* Try the aperture driver first */
219 if ((fd
= open(DEV_APERTURE
, O_RDWR
)) >= 0) {
220 /* Try to map a page at the VGA address */
221 base
= mmap((caddr_t
)0, 4096, PROT_READ
| PROT_WRITE
,
222 MAP_FLAGS
, fd
, (off_t
)0xA0000 + BUS_BASE
);
224 if (base
!= MAP_FAILED
) {
225 munmap((caddr_t
)base
, 4096);
228 xf86Msg(X_INFO
, "checkDevMem: using aperture driver %s\n",
233 xf86Msg(X_WARNING
, "checkDevMem: failed to mmap %s (%s)\n",
234 DEV_APERTURE
, strerror(errno
));
239 if ((fd
= open(DEV_MEM
, O_RDWR
)) >= 0) {
240 /* Try to map a page at the VGA address */
241 base
= mmap((caddr_t
)0, 4096, PROT_READ
| PROT_WRITE
,
242 MAP_FLAGS
, fd
, (off_t
)0xA0000 + BUS_BASE
);
244 if (base
!= MAP_FAILED
) {
245 munmap((caddr_t
)base
, 4096);
251 xf86Msg(X_WARNING
, "checkDevMem: failed to mmap %s (%s)\n",
252 DEV_MEM
, strerror(errno
));
257 #ifndef HAS_APERTURE_DRV
258 xf86Msg(X_WARNING
, "checkDevMem: failed to open/mmap %s (%s)\n",
259 DEV_MEM
, strerror(errno
));
262 xf86Msg(X_WARNING
, "checkDevMem: failed to open %s and %s\n"
263 "\t(%s)\n", DEV_APERTURE
, DEV_MEM
, strerror(errno
));
264 #else /* __OpenBSD__ */
265 xf86Msg(X_WARNING
, "checkDevMem: failed to open %s and %s\n"
266 "\t(%s)\n%s", DEV_APERTURE
, DEV_MEM
, strerror(errno
),
268 #endif /* __OpenBSD__ */
270 xf86ErrorF("\tlinear framebuffer access unavailable\n");
277 xf86OSInitVidMem(VidMemInfoPtr pVidMem
)
280 pVidMem
->linearSupported
= useDevMem
;
283 xf86Msg(X_PROBED
,"Machine type has 8/16 bit access\n");
284 pVidMem
->mapMem
= mapVidMem
;
285 pVidMem
->unmapMem
= unmapVidMem
;
287 xf86Msg(X_PROBED
,"Machine needs sparse mapping\n");
288 pVidMem
->mapMem
= mapVidMemSparse
;
289 pVidMem
->unmapMem
= unmapVidMemSparse
;
292 axpSystem
= bsdGetAXP();
293 hae_thresh
= xf86AXPParams
[axpSystem
].hae_thresh
;
294 hae_mask
= xf86AXPParams
[axpSystem
].hae_mask
;
295 sparse_size
= xf86AXPParams
[axpSystem
].size
;
296 #endif /* __NetBSD__ */
298 pVidMem
->initialised
= TRUE
;
302 mapVidMem(int ScreenNum
, unsigned long Base
, unsigned long Size
, int flags
)
307 Base
= Base
& ((1L<<32) - 1);
313 FatalError("xf86MapVidMem: failed to open %s (%s)\n",
314 DEV_MEM
, strerror(errno
));
316 base
= mmap((caddr_t
)0, Size
,
317 (flags
& VIDMEM_READONLY
) ?
318 PROT_READ
: (PROT_READ
| PROT_WRITE
),
319 MAP_FLAGS
, devMemFd
, (off_t
)Base
+ BUS_BASE_BWX
);
320 if (base
== MAP_FAILED
)
322 FatalError("%s: could not mmap %s [s=%lx,a=%lx] (%s)\n",
323 "xf86MapVidMem", DEV_MEM
, Size
, Base
,
329 /* else, mmap /dev/vga */
330 if ((unsigned long)Base
< 0xA0000 || (unsigned long)Base
>= 0xC0000)
332 FatalError("%s: Address 0x%lx outside allowable range\n",
333 "xf86MapVidMem", Base
);
336 (flags
& VIDMEM_READONLY
) ?
337 PROT_READ
: (PROT_READ
| PROT_WRITE
),
338 MAP_FLAGS
, xf86Info
.screenFd
,
339 (unsigned long)Base
+ BUS_BASE
);
340 if (base
== MAP_FAILED
)
342 FatalError("xf86MapVidMem: Could not mmap /dev/vga (%s)\n",
349 unmapVidMem(int ScreenNum
, pointer Base
, unsigned long Size
)
351 munmap((caddr_t
)Base
, Size
);
355 * Read BIOS via mmap()ing DEV_MEM
359 xf86ReadBIOS(unsigned long Base
, unsigned long Offset
, unsigned char *Buf
,
367 if (devMemFd
== -1) {
371 psize
= xf86getpagesize();
372 Offset
+= Base
& (psize
- 1);
373 Base
&= ~(psize
- 1);
374 mlen
= (Offset
+ Len
+ psize
- 1) & ~(psize
- 1);
375 ptr
= (unsigned char *)mmap((caddr_t
)0, mlen
, PROT_READ
,
376 MAP_SHARED
, devMemFd
, (off_t
)Base
+BUS_BASE
);
380 "xf86ReadBIOS: %s mmap[s=%x,a=%lx,o=%lx] failed (%s)\n",
381 DEV_MEM
, Len
, Base
, Offset
, strerror(errno
));
385 xf86MsgVerb(X_INFO
, 3, "xf86ReadBIOS: BIOS at 0x%08x has signature 0x%04x\n",
386 Base
, ptr
[0] | (ptr
[1] << 8));
388 (void)memcpy(Buf
, (void *)(ptr
+ Offset
), Len
);
389 (void)munmap((caddr_t
)ptr
, mlen
);
391 xf86MsgVerb(X_INFO
, 3, "xf86ReadBIOS(%x, %x, Buf, %x)"
392 "-> %02x %02x %02x %02x...\n",
393 Base
, Offset
, Len
, Buf
[0], Buf
[1], Buf
[2], Buf
[3]);
399 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
401 extern int ioperm(unsigned long from
, unsigned long num
, int on
);
406 if (!ioperm(0, 65536, TRUE
))
417 #endif /* __FreeBSD_kernel__ || __OpenBSD__ */
424 alpha_pci_io_enable(1);
431 alpha_pci_io_enable(0);
434 #endif /* USE_ALPHA_PIO */
436 /***************************************************************************/
437 /* Interrupt Handling section */
438 /***************************************************************************/
441 xf86DisableInterrupts()
448 xf86EnableInterrupts()
454 #define vuip volatile unsigned int *
456 static unsigned long msb_set
= 0;
457 static pointer memSBase
= 0;
458 static pointer memBase
= 0;
460 extern int readDense8(pointer Base
, register unsigned long Offset
);
461 extern int readDense16(pointer Base
, register unsigned long Offset
);
462 extern int readDense32(pointer Base
, register unsigned long Offset
);
464 writeDenseNB8(int Value
, pointer Base
, register unsigned long Offset
);
466 writeDenseNB16(int Value
, pointer Base
, register unsigned long Offset
);
468 writeDenseNB32(int Value
, pointer Base
, register unsigned long Offset
);
470 writeDense8(int Value
, pointer Base
, register unsigned long Offset
);
472 writeDense16(int Value
, pointer Base
, register unsigned long Offset
);
474 writeDense32(int Value
, pointer Base
, register unsigned long Offset
);
476 static int readSparse8(pointer Base
, register unsigned long Offset
);
477 static int readSparse16(pointer Base
, register unsigned long Offset
);
478 static int readSparse32(pointer Base
, register unsigned long Offset
);
480 writeSparseNB8(int Value
, pointer Base
, register unsigned long Offset
);
482 writeSparseNB16(int Value
, pointer Base
, register unsigned long Offset
);
484 writeSparseNB32(int Value
, pointer Base
, register unsigned long Offset
);
486 writeSparse8(int Value
, pointer Base
, register unsigned long Offset
);
488 writeSparse16(int Value
, pointer Base
, register unsigned long Offset
);
490 writeSparse32(int Value
, pointer Base
, register unsigned long Offset
);
492 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
493 extern int sysarch(int, void *);
502 sethae(u_int64_t hae
)
504 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
506 #define ALPHA_SETHAE 0
510 return (sysarch(ALPHA_SETHAE
, (char *)&p
));
516 #endif /* __NetBSD__ */
519 mapVidMemSparse(int ScreenNum
, unsigned long Base
, unsigned long Size
, int flags
)
521 static Bool was_here
= FALSE
;
528 xf86WriteMmio8
= writeSparse8
;
529 xf86WriteMmio16
= writeSparse16
;
530 xf86WriteMmio32
= writeSparse32
;
531 xf86WriteMmioNB8
= writeSparseNB8
;
532 xf86WriteMmioNB16
= writeSparseNB16
;
533 xf86WriteMmioNB32
= writeSparseNB32
;
534 xf86ReadMmio8
= readSparse8
;
535 xf86ReadMmio16
= readSparse16
;
536 xf86ReadMmio32
= readSparse32
;
538 memBase
= mmap((caddr_t
)0, 0x100000000,
539 PROT_READ
| PROT_WRITE
,
540 MAP_SHARED
, devMemFd
,
542 memSBase
= mmap((caddr_t
)0, 0x100000000,
543 PROT_READ
| PROT_WRITE
,
544 MAP_SHARED
, devMemFd
,
545 (off_t
) BUS_BASE_BWX
);
547 if (memSBase
== MAP_FAILED
|| memBase
== MAP_FAILED
) {
548 FatalError("xf86MapVidMem: Could not mmap framebuffer (%s)\n",
552 return (pointer
)((unsigned long)memBase
+ Base
);
556 unmapVidMemSparse(int ScreenNum
, pointer Base
, unsigned long Size
)
561 readSparse8(pointer Base
, register unsigned long Offset
)
563 register unsigned long result
, shift
;
564 register unsigned long msb
;
566 Offset
+= (unsigned long)Base
- (unsigned long)memBase
;
567 shift
= (Offset
& 0x3) << 3;
568 if (Offset
>= (hae_thresh
)) {
569 msb
= Offset
& hae_mask
;
571 if (msb_set
!= msb
) {
578 result
= *(vuip
) ((unsigned long)memSBase
+ (Offset
<< 5));
580 return 0xffUL
& result
;
584 readSparse16(pointer Base
, register unsigned long Offset
)
586 register unsigned long result
, shift
;
587 register unsigned long msb
;
590 Offset
+= (unsigned long)Base
- (unsigned long)memBase
;
591 shift
= (Offset
& 0x2) << 3;
592 if (Offset
>= (hae_thresh
)) {
593 msb
= Offset
& hae_mask
;
595 if (msb_set
!= msb
) {
602 result
= *(vuip
)((unsigned long)memSBase
+(Offset
<<5)+(1<<(5-2)));
604 return 0xffffUL
& result
;
608 readSparse32(pointer Base
, register unsigned long Offset
)
611 return *(vuip
)((unsigned long)Base
+(Offset
));
615 writeSparse8(int Value
, pointer Base
, register unsigned long Offset
)
617 register unsigned long msb
;
618 register unsigned int b
= Value
& 0xffU
;
621 Offset
+= (unsigned long)Base
- (unsigned long)memBase
;
622 if (Offset
>= (hae_thresh
)) {
623 msb
= Offset
& hae_mask
;
625 if (msb_set
!= msb
) {
632 *(vuip
) ((unsigned long)memSBase
+ (Offset
<< 5)) = b
* 0x01010101;
636 writeSparse16(int Value
, pointer Base
, register unsigned long Offset
)
638 register unsigned long msb
;
639 register unsigned int w
= Value
& 0xffffU
;
642 Offset
+= (unsigned long)Base
- (unsigned long)memBase
;
643 if (Offset
>= (hae_thresh
)) {
644 msb
= Offset
& hae_mask
;
646 if (msb_set
!= msb
) {
653 *(vuip
)((unsigned long)memSBase
+(Offset
<<5)+(1<<(5-2))) =
659 writeSparse32(int Value
, pointer Base
, register unsigned long Offset
)
662 *(vuip
)((unsigned long)Base
+ (Offset
)) = Value
;
667 writeSparseNB8(int Value
, pointer Base
, register unsigned long Offset
)
669 register unsigned long msb
;
670 register unsigned int b
= Value
& 0xffU
;
672 Offset
+= (unsigned long)Base
- (unsigned long)memBase
;
673 if (Offset
>= (hae_thresh
)) {
674 msb
= Offset
& hae_mask
;
676 if (msb_set
!= msb
) {
683 *(vuip
) ((unsigned long)memSBase
+ (Offset
<< 5)) = b
* 0x01010101;
687 writeSparseNB16(int Value
, pointer Base
, register unsigned long Offset
)
689 register unsigned long msb
;
690 register unsigned int w
= Value
& 0xffffU
;
692 Offset
+= (unsigned long)Base
- (unsigned long)memBase
;
693 if (Offset
>= (hae_thresh
)) {
694 msb
= Offset
& hae_mask
;
696 if (msb_set
!= msb
) {
703 *(vuip
)((unsigned long)memSBase
+(Offset
<<5)+(1<<(5-2))) =
708 writeSparseNB32(int Value
, pointer Base
, register unsigned long Offset
)
710 *(vuip
)((unsigned long)Base
+ (Offset
)) = Value
;
714 _X_EXPORT
void (*xf86WriteMmio8
)(int Value
, pointer Base
, unsigned long Offset
)
716 _X_EXPORT
void (*xf86WriteMmio16
)(int Value
, pointer Base
, unsigned long Offset
)
718 _X_EXPORT
void (*xf86WriteMmio32
)(int Value
, pointer Base
, unsigned long Offset
)
720 _X_EXPORT
void (*xf86WriteMmioNB8
)(int Value
, pointer Base
, unsigned long Offset
)
722 _X_EXPORT
void (*xf86WriteMmioNB16
)(int Value
, pointer Base
, unsigned long Offset
)
724 _X_EXPORT
void (*xf86WriteMmioNB32
)(int Value
, pointer Base
, unsigned long Offset
)
726 _X_EXPORT
int (*xf86ReadMmio8
)(pointer Base
, unsigned long Offset
)
728 _X_EXPORT
int (*xf86ReadMmio16
)(pointer Base
, unsigned long Offset
)
730 _X_EXPORT
int (*xf86ReadMmio32
)(pointer Base
, unsigned long Offset
)