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