1 /*******************************************************************************
2 for Alpha Linux
3 *******************************************************************************/
4
5 /*
6 * Create a dependency that should be immune from the effect of register
7 * renaming as is commonly seen in superscalar processors. This should
8 * insert a minimum of 100-ns delays between reads/writes at clock rates
9 * up to 100 MHz---GGL
10 *
11 * Slowbcopy(char *src, char *dst, int count)
12 *
13 */
14
15 #ifdef HAVE_XORG_CONFIG_H
16 #include <xorg-config.h>
17 #endif
18
19 #include <X11/X.h>
20 #include "xf86.h"
21 #include "xf86Priv.h"
22 #include "xf86_OSlib.h"
23 #include "compiler.h"
24
25 static int really_slow_bcopy;
26
27 void
xf86SetReallySlowBcopy(void)28 xf86SetReallySlowBcopy(void)
29 {
30 really_slow_bcopy = 1;
31 }
32
33 #if defined(__i386__) || defined(__amd64__)
34 static void
xf86_really_slow_bcopy(unsigned char * src,unsigned char * dst,int len)35 xf86_really_slow_bcopy(unsigned char *src, unsigned char *dst, int len)
36 {
37 while (len--) {
38 *dst++ = *src++;
39 outb(0x80, 0x00);
40 }
41 }
42 #endif
43
44 /* The outb() isn't needed on my machine, but who knows ... -- ost */
45 void
xf86SlowBcopy(unsigned char * src,unsigned char * dst,int len)46 xf86SlowBcopy(unsigned char *src, unsigned char *dst, int len)
47 {
48 #if defined(__i386__) || defined(__amd64__)
49 if (really_slow_bcopy) {
50 xf86_really_slow_bcopy(src, dst, len);
51 return;
52 }
53 #endif
54 while (len--)
55 *dst++ = *src++;
56 }
57
58 #ifdef __alpha__
59
60 #ifdef __linux__
61
62 unsigned long _bus_base(void);
63
64 #define useSparse() (!_bus_base())
65
66 #define SPARSE (7)
67
68 #else
69
70 #define useSparse() 0
71
72 #define SPARSE 0
73
74 #endif
75
76 void
xf86SlowBCopyFromBus(unsigned char * src,unsigned char * dst,int count)77 xf86SlowBCopyFromBus(unsigned char *src, unsigned char *dst, int count)
78 {
79 if (useSparse()) {
80 unsigned long addr;
81 long result;
82
83 addr = (unsigned long) src;
84 while (count) {
85 result = *(volatile int *) addr;
86 result >>= ((addr >> SPARSE) & 3) * 8;
87 *dst++ = (unsigned char) (0xffUL & result);
88 addr += 1 << SPARSE;
89 count--;
90 outb(0x80, 0x00);
91 }
92 }
93 else
94 xf86SlowBcopy(src, dst, count);
95 }
96
97 void
xf86SlowBCopyToBus(unsigned char * src,unsigned char * dst,int count)98 xf86SlowBCopyToBus(unsigned char *src, unsigned char *dst, int count)
99 {
100 if (useSparse()) {
101 unsigned long addr;
102
103 addr = (unsigned long) dst;
104 while (count) {
105 *(volatile unsigned int *) addr =
106 (unsigned short) (*src) * 0x01010101;
107 src++;
108 addr += 1 << SPARSE;
109 count--;
110 outb(0x80, 0x00);
111 }
112 }
113 else
114 xf86SlowBcopy(src, dst, count);
115 }
116 #endif
117