First import
[xorg_rtime.git] / xorg-server-1.4 / hw / xfree86 / os-support / bsd / alpha_video.c
bloba1b19d0f6131ef8c1ca04356710a6d1b4ee86109
1 /*
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
14 * implied warranty.
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>
28 #endif
30 #include <X11/X.h>
31 #include "xf86.h"
32 #include "xf86Priv.h"
34 #include <sys/param.h>
35 #ifndef __NetBSD__
36 # include <sys/sysctl.h>
37 # if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
38 # include <machine/sysarch.h>
39 # endif
40 # else
41 # include <machine/sysarch.h>
42 #endif
44 #include "xf86Axp.h"
46 #include "xf86_OSlib.h"
47 #include "xf86OSpriv.h"
49 #if defined(__NetBSD__) && !defined(MAP_FILE)
50 #define MAP_FLAGS MAP_SHARED
51 #else
52 #define MAP_FLAGS (MAP_FILE | MAP_SHARED)
53 #endif
55 #ifndef MAP_FAILED
56 #define MAP_FAILED ((caddr_t)-1)
57 #endif
59 axpDevice bsdGetAXP(void);
61 #ifndef __NetBSD__
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;
70 static unsigned long
71 memory_base(void)
73 static unsigned long base = 0;
75 if (base == 0) {
76 size_t len = sizeof(base);
77 int error;
78 #ifdef __OpenBSD__
79 int mib[3];
81 mib[0] = CTL_MACHDEP;
82 mib[1] = CPU_CHIPSET;
83 mib[2] = CPU_CHIPSET_MEM;
85 if ((error = sysctl(mib, 3, &base, &len, NULL, 0)) < 0)
86 #else
87 if ((error = sysctlbyname("hw.chipset.memory", &base, &len,
88 0, 0)) < 0)
89 #endif
90 FatalError("xf86MapVidMem: can't find memory\n");
93 return base;
96 static int
97 has_bwx(void)
99 static int bwx = 0;
100 size_t len = sizeof(bwx);
101 int error;
102 #ifdef __OpenBSD__
103 int mib[3];
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)
110 return FALSE;
111 else
112 return bwx;
113 #else
114 if ((error = sysctlbyname("hw.chipset.bwx", &bwx, &len, 0, 0)) < 0)
115 return FALSE;
116 else
117 return bwx;
118 #endif
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;
126 static void
127 init_abw(void)
129 if (abw_count < 0) {
130 abw_count = alpha_bus_getwindows(ALPHA_BUS_TYPE_PCI_MEM, &abw);
131 if (abw_count <= 0)
132 FatalError("init_abw: alpha_bus_getwindows failed\n");
136 static int
137 has_bwx(void)
139 if (abw_count < 0)
140 init_abw();
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;
147 static unsigned long
148 dense_base(void)
150 if (abw_count < 0)
151 init_abw();
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;
159 static unsigned long
160 memory_base(void)
162 if (abw_count < 0)
163 init_abw();
165 if (abw_count > 0) {
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;
169 } else {
170 xf86Msg(X_INFO, "no memory base\n"); /* XXXX */
171 return 0;
174 #endif /* __NetBSD__ */
176 #define BUS_BASE dense_base()
177 #define BUS_BASE_BWX memory_base()
179 /***************************************************************************/
180 /* Video Memory Mapping section */
181 /***************************************************************************/
183 #ifdef __OpenBSD__
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"
187 #endif
189 static Bool useDevMem = FALSE;
190 static int devMemFd = -1;
192 #ifdef HAS_APERTURE_DRV
193 #define DEV_APERTURE "/dev/xf86"
194 #endif
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
204 * "warn" is TRUE.
206 static void
207 checkDevMem(Bool warn)
209 static Bool devMemChecked = FALSE;
210 int fd;
211 pointer base;
213 if (devMemChecked)
214 return;
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);
226 devMemFd = fd;
227 useDevMem = TRUE;
228 xf86Msg(X_INFO, "checkDevMem: using aperture driver %s\n",
229 DEV_APERTURE);
230 return;
231 } else {
232 if (warn) {
233 xf86Msg(X_WARNING, "checkDevMem: failed to mmap %s (%s)\n",
234 DEV_APERTURE, strerror(errno));
238 #endif
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);
246 devMemFd = fd;
247 useDevMem = TRUE;
248 return;
249 } else {
250 if (warn) {
251 xf86Msg(X_WARNING, "checkDevMem: failed to mmap %s (%s)\n",
252 DEV_MEM, strerror(errno));
256 if (warn) {
257 #ifndef HAS_APERTURE_DRV
258 xf86Msg(X_WARNING, "checkDevMem: failed to open/mmap %s (%s)\n",
259 DEV_MEM, strerror(errno));
260 #else
261 #ifndef __OpenBSD__
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),
267 SYSCTL_MSG);
268 #endif /* __OpenBSD__ */
269 #endif
270 xf86ErrorF("\tlinear framebuffer access unavailable\n");
272 useDevMem = FALSE;
273 return;
276 void
277 xf86OSInitVidMem(VidMemInfoPtr pVidMem)
279 checkDevMem(TRUE);
280 pVidMem->linearSupported = useDevMem;
282 if (has_bwx()) {
283 xf86Msg(X_PROBED,"Machine type has 8/16 bit access\n");
284 pVidMem->mapMem = mapVidMem;
285 pVidMem->unmapMem = unmapVidMem;
286 } else {
287 xf86Msg(X_PROBED,"Machine needs sparse mapping\n");
288 pVidMem->mapMem = mapVidMemSparse;
289 pVidMem->unmapMem = unmapVidMemSparse;
290 #ifndef __NetBSD__
291 if (axpSystem == -1)
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;
301 static pointer
302 mapVidMem(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
304 pointer base;
306 checkDevMem(FALSE);
307 Base = Base & ((1L<<32) - 1);
309 if (useDevMem)
311 if (devMemFd < 0)
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,
324 strerror(errno));
326 return(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);
335 base = mmap(0, Size,
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",
343 strerror(errno));
345 return(base);
348 static void
349 unmapVidMem(int ScreenNum, pointer Base, unsigned long Size)
351 munmap((caddr_t)Base, Size);
355 * Read BIOS via mmap()ing DEV_MEM
358 _X_EXPORT int
359 xf86ReadBIOS(unsigned long Base, unsigned long Offset, unsigned char *Buf,
360 int Len)
362 unsigned char *ptr;
363 int psize;
364 int mlen;
366 checkDevMem(TRUE);
367 if (devMemFd == -1) {
368 return(-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);
377 if ((long)ptr == -1)
379 xf86Msg(X_WARNING,
380 "xf86ReadBIOS: %s mmap[s=%x,a=%lx,o=%lx] failed (%s)\n",
381 DEV_MEM, Len, Base, Offset, strerror(errno));
382 return(-1);
384 #ifdef DEBUG
385 xf86MsgVerb(X_INFO, 3, "xf86ReadBIOS: BIOS at 0x%08x has signature 0x%04x\n",
386 Base, ptr[0] | (ptr[1] << 8));
387 #endif
388 (void)memcpy(Buf, (void *)(ptr + Offset), Len);
389 (void)munmap((caddr_t)ptr, mlen);
390 #ifdef DEBUG
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]);
394 #endif
395 return(Len);
399 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__)
401 extern int ioperm(unsigned long from, unsigned long num, int on);
403 _X_EXPORT Bool
404 xf86EnableIO()
406 if (!ioperm(0, 65536, TRUE))
407 return TRUE;
408 return FALSE;
411 _X_EXPORT void
412 xf86DisableIO()
414 return;
417 #endif /* __FreeBSD_kernel__ || __OpenBSD__ */
419 #ifdef USE_ALPHA_PIO
421 Bool
422 xf86EnableIO()
424 alpha_pci_io_enable(1);
425 return TRUE;
428 void
429 xf86DisableIO()
431 alpha_pci_io_enable(0);
434 #endif /* USE_ALPHA_PIO */
436 /***************************************************************************/
437 /* Interrupt Handling section */
438 /***************************************************************************/
440 _X_EXPORT Bool
441 xf86DisableInterrupts()
444 return(TRUE);
447 _X_EXPORT void
448 xf86EnableInterrupts()
450 return;
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);
463 extern void
464 writeDenseNB8(int Value, pointer Base, register unsigned long Offset);
465 extern void
466 writeDenseNB16(int Value, pointer Base, register unsigned long Offset);
467 extern void
468 writeDenseNB32(int Value, pointer Base, register unsigned long Offset);
469 extern void
470 writeDense8(int Value, pointer Base, register unsigned long Offset);
471 extern void
472 writeDense16(int Value, pointer Base, register unsigned long Offset);
473 extern void
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);
479 static void
480 writeSparseNB8(int Value, pointer Base, register unsigned long Offset);
481 static void
482 writeSparseNB16(int Value, pointer Base, register unsigned long Offset);
483 static void
484 writeSparseNB32(int Value, pointer Base, register unsigned long Offset);
485 static void
486 writeSparse8(int Value, pointer Base, register unsigned long Offset);
487 static void
488 writeSparse16(int Value, pointer Base, register unsigned long Offset);
489 static void
490 writeSparse32(int Value, pointer Base, register unsigned long Offset);
492 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
493 extern int sysarch(int, void *);
494 #endif
496 struct parms {
497 u_int64_t hae;
500 #ifndef __NetBSD__
501 static int
502 sethae(u_int64_t hae)
504 #if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
505 #ifndef ALPHA_SETHAE
506 #define ALPHA_SETHAE 0
507 #endif
508 struct parms p;
509 p.hae = hae;
510 return (sysarch(ALPHA_SETHAE, (char *)&p));
511 #endif
512 #ifdef __OpenBSD__
513 return -1;
514 #endif
516 #endif /* __NetBSD__ */
518 static pointer
519 mapVidMemSparse(int ScreenNum, unsigned long Base, unsigned long Size, int flags)
521 static Bool was_here = FALSE;
523 if (!was_here) {
524 was_here = TRUE;
526 checkDevMem(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,
541 (off_t) BUS_BASE);
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",
549 strerror(errno));
552 return (pointer)((unsigned long)memBase + Base);
555 static void
556 unmapVidMemSparse(int ScreenNum, pointer Base, unsigned long Size)
560 static int
561 readSparse8(pointer Base, register unsigned long Offset)
563 register unsigned long result, shift;
564 register unsigned long msb;
565 mem_barrier();
566 Offset += (unsigned long)Base - (unsigned long)memBase;
567 shift = (Offset & 0x3) << 3;
568 if (Offset >= (hae_thresh)) {
569 msb = Offset & hae_mask;
570 Offset -= msb;
571 if (msb_set != msb) {
572 #ifndef __NetBSD__
573 sethae(msb);
574 #endif
575 msb_set = msb;
578 result = *(vuip) ((unsigned long)memSBase + (Offset << 5));
579 result >>= shift;
580 return 0xffUL & result;
583 static int
584 readSparse16(pointer Base, register unsigned long Offset)
586 register unsigned long result, shift;
587 register unsigned long msb;
589 mem_barrier();
590 Offset += (unsigned long)Base - (unsigned long)memBase;
591 shift = (Offset & 0x2) << 3;
592 if (Offset >= (hae_thresh)) {
593 msb = Offset & hae_mask;
594 Offset -= msb;
595 if (msb_set != msb) {
596 #ifndef __NetBSD__
597 sethae(msb);
598 #endif
599 msb_set = msb;
602 result = *(vuip)((unsigned long)memSBase+(Offset<<5)+(1<<(5-2)));
603 result >>= shift;
604 return 0xffffUL & result;
607 static int
608 readSparse32(pointer Base, register unsigned long Offset)
610 mem_barrier();
611 return *(vuip)((unsigned long)Base+(Offset));
614 static void
615 writeSparse8(int Value, pointer Base, register unsigned long Offset)
617 register unsigned long msb;
618 register unsigned int b = Value & 0xffU;
620 write_mem_barrier();
621 Offset += (unsigned long)Base - (unsigned long)memBase;
622 if (Offset >= (hae_thresh)) {
623 msb = Offset & hae_mask;
624 Offset -= msb;
625 if (msb_set != msb) {
626 #ifndef __NetBSD__
627 sethae(msb);
628 #endif
629 msb_set = msb;
632 *(vuip) ((unsigned long)memSBase + (Offset << 5)) = b * 0x01010101;
635 static void
636 writeSparse16(int Value, pointer Base, register unsigned long Offset)
638 register unsigned long msb;
639 register unsigned int w = Value & 0xffffU;
641 write_mem_barrier();
642 Offset += (unsigned long)Base - (unsigned long)memBase;
643 if (Offset >= (hae_thresh)) {
644 msb = Offset & hae_mask;
645 Offset -= msb;
646 if (msb_set != msb) {
647 #ifndef __NetBSD__
648 sethae(msb);
649 #endif
650 msb_set = msb;
653 *(vuip)((unsigned long)memSBase+(Offset<<5)+(1<<(5-2))) =
654 w * 0x00010001;
658 static void
659 writeSparse32(int Value, pointer Base, register unsigned long Offset)
661 write_mem_barrier();
662 *(vuip)((unsigned long)Base + (Offset)) = Value;
663 return;
666 static void
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;
675 Offset -= msb;
676 if (msb_set != msb) {
677 #ifndef __NetBSD__
678 sethae(msb);
679 #endif
680 msb_set = msb;
683 *(vuip) ((unsigned long)memSBase + (Offset << 5)) = b * 0x01010101;
686 static void
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 ;
695 Offset -= msb;
696 if (msb_set != msb) {
697 #ifndef __NetBSD__
698 sethae(msb);
699 #endif
700 msb_set = msb;
703 *(vuip)((unsigned long)memSBase+(Offset<<5)+(1<<(5-2))) =
704 w * 0x00010001;
707 static void
708 writeSparseNB32(int Value, pointer Base, register unsigned long Offset)
710 *(vuip)((unsigned long)Base + (Offset)) = Value;
711 return;
714 _X_EXPORT void (*xf86WriteMmio8)(int Value, pointer Base, unsigned long Offset)
715 = writeDense8;
716 _X_EXPORT void (*xf86WriteMmio16)(int Value, pointer Base, unsigned long Offset)
717 = writeDense16;
718 _X_EXPORT void (*xf86WriteMmio32)(int Value, pointer Base, unsigned long Offset)
719 = writeDense32;
720 _X_EXPORT void (*xf86WriteMmioNB8)(int Value, pointer Base, unsigned long Offset)
721 = writeDenseNB8;
722 _X_EXPORT void (*xf86WriteMmioNB16)(int Value, pointer Base, unsigned long Offset)
723 = writeDenseNB16;
724 _X_EXPORT void (*xf86WriteMmioNB32)(int Value, pointer Base, unsigned long Offset)
725 = writeDenseNB32;
726 _X_EXPORT int (*xf86ReadMmio8)(pointer Base, unsigned long Offset)
727 = readDense8;
728 _X_EXPORT int (*xf86ReadMmio16)(pointer Base, unsigned long Offset)
729 = readDense16;
730 _X_EXPORT int (*xf86ReadMmio32)(pointer Base, unsigned long Offset)
731 = readDense32;