1#ifndef _ASM_IO_H
2#define _ASM_IO_H
3
4#include <linux/config.h>
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39#define IO_SPACE_LIMIT 0xffff
40
41#define XQUAD_PORTIO_BASE 0xfe400000
42#define XQUAD_PORTIO_QUAD 0x40000
43#define XQUAD_PORTIO_LEN 0x80000
44
45#ifdef __KERNEL__
46
47#include <linux/vmalloc.h>
48
49
50
51
52
53#if CONFIG_DEBUG_IOVIRT
54 extern void *__io_virt_debug(unsigned long x, const char *file, int line);
55 extern unsigned long __io_phys_debug(unsigned long x, const char *file, int line);
56 #define __io_virt(x) __io_virt_debug((unsigned long)(x), __FILE__, __LINE__)
57
58#else
59 #define __io_virt(x) ((void *)(x))
60
61#endif
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76static inline unsigned long virt_to_phys(volatile void * address)
77{
78 return __pa(address);
79}
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94static inline void * phys_to_virt(unsigned long address)
95{
96 return __va(address);
97}
98
99
100
101
102#ifdef CONFIG_HIGHMEM64G
103#define page_to_phys(page) ((u64)(page - mem_map) << PAGE_SHIFT)
104#else
105#define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT)
106#endif
107
108extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
109
110
111
112
113
114
115
116
117
118
119
120
121
122static inline void * ioremap (unsigned long offset, unsigned long size)
123{
124 return __ioremap(offset, size, 0);
125}
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147static inline void * ioremap_nocache (unsigned long offset, unsigned long size)
148{
149 return __ioremap(offset, size, _PAGE_PCD);
150}
151
152extern void iounmap(void *addr);
153
154
155
156
157
158
159extern void *bt_ioremap(unsigned long offset, unsigned long size);
160extern void bt_iounmap(void *addr, unsigned long size);
161
162
163
164
165#define virt_to_bus virt_to_phys
166#define bus_to_virt phys_to_virt
167#define page_to_bus page_to_phys
168
169
170
171
172
173
174
175
176#define readb(addr) (*(volatile unsigned char *) __io_virt(addr))
177#define readw(addr) (*(volatile unsigned short *) __io_virt(addr))
178#define readl(addr) (*(volatile unsigned int *) __io_virt(addr))
179#define __raw_readb readb
180#define __raw_readw readw
181#define __raw_readl readl
182
183#define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b))
184#define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b))
185#define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b))
186#define __raw_writeb writeb
187#define __raw_writew writew
188#define __raw_writel writel
189
190#define memset_io(a,b,c) __memset(__io_virt(a),(b),(c))
191#define memcpy_fromio(a,b,c) __memcpy((a),__io_virt(b),(c))
192#define memcpy_toio(a,b,c) __memcpy(__io_virt(a),(b),(c))
193
194
195
196
197
198
199
200
201
202#define __ISA_IO_base ((char *)(PAGE_OFFSET))
203
204#define isa_readb(a) readb(__ISA_IO_base + (a))
205#define isa_readw(a) readw(__ISA_IO_base + (a))
206#define isa_readl(a) readl(__ISA_IO_base + (a))
207#define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a))
208#define isa_writew(w,a) writew(w,__ISA_IO_base + (a))
209#define isa_writel(l,a) writel(l,__ISA_IO_base + (a))
210#define isa_memset_io(a,b,c) memset_io(__ISA_IO_base + (a),(b),(c))
211#define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),__ISA_IO_base + (b),(c))
212#define isa_memcpy_toio(a,b,c) memcpy_toio(__ISA_IO_base + (a),(b),(c))
213
214
215
216
217
218
219#define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__io_virt(b),(c),(d))
220#define isa_eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__io_virt(__ISA_IO_base + (b)),(c),(d))
221
222
223
224
225
226
227
228
229
230
231
232
233static inline int check_signature(unsigned long io_addr,
234 const unsigned char *signature, int length)
235{
236 int retval = 0;
237 do {
238 if (readb(io_addr) != *signature)
239 goto out;
240 io_addr++;
241 signature++;
242 length--;
243 } while (length);
244 retval = 1;
245out:
246 return retval;
247}
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263static inline int isa_check_signature(unsigned long io_addr,
264 const unsigned char *signature, int length)
265{
266 int retval = 0;
267 do {
268 if (isa_readb(io_addr) != *signature)
269 goto out;
270 io_addr++;
271 signature++;
272 length--;
273 } while (length);
274 retval = 1;
275out:
276 return retval;
277}
278
279
280
281
282
283
284
285
286
287#if defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE)
288
289static inline void flush_write_buffers(void)
290{
291 __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory");
292}
293
294#define dma_cache_inv(_start,_size) flush_write_buffers()
295#define dma_cache_wback(_start,_size) flush_write_buffers()
296#define dma_cache_wback_inv(_start,_size) flush_write_buffers()
297
298#else
299
300
301
302#define dma_cache_inv(_start,_size) do { } while (0)
303#define dma_cache_wback(_start,_size) do { } while (0)
304#define dma_cache_wback_inv(_start,_size) do { } while (0)
305#define flush_write_buffers()
306
307#endif
308
309#endif
310
311#ifdef SLOW_IO_BY_JUMPING
312#define __SLOW_DOWN_IO "\njmp 1f\n1:\tjmp 1f\n1:"
313#else
314#define __SLOW_DOWN_IO "\noutb %%al,$0x80"
315#endif
316
317#ifdef REALLY_SLOW_IO
318#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO
319#else
320#define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO
321#endif
322
323#ifdef CONFIG_MULTIQUAD
324extern void *xquad_portio;
325#endif
326
327
328
329
330#define __OUT1(s,x) \
331static inline void out##s(unsigned x value, unsigned short port) {
332
333#define __OUT2(s,s1,s2) \
334__asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
335
336#if defined (CONFIG_MULTIQUAD) && !defined(STANDALONE)
337#define __OUTQ(s,ss,x) \
338static inline void out##ss(unsigned x value, unsigned short port) { \
339 if (xquad_portio) \
340 write##s(value, (unsigned long) xquad_portio + port); \
341 else \
342 out##ss##_local(value, port); \
343} \
344static inline void out##ss##_quad(unsigned x value, unsigned short port, int quad) { \
345 if (xquad_portio) \
346 write##s(value, (unsigned long) xquad_portio + (XQUAD_PORTIO_QUAD*quad)\
347 + port); \
348}
349
350#define __INQ(s,ss) \
351static inline RETURN_TYPE in##ss(unsigned short port) { \
352 if (xquad_portio) \
353 return read##s((unsigned long) xquad_portio + port); \
354 else \
355 return in##ss##_local(port); \
356} \
357static inline RETURN_TYPE in##ss##_quad(unsigned short port, int quad) { \
358 if (xquad_portio) \
359 return read##s((unsigned long) xquad_portio + (XQUAD_PORTIO_QUAD*quad)\
360 + port); \
361 else\
362 return 0;\
363}
364#endif
365
366#if !defined(CONFIG_MULTIQUAD) || defined(STANDALONE)
367#define __OUT(s,s1,x) \
368__OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
369__OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));}
370#else
371
372#define __OUT(s,s1,x) \
373__OUT1(s##_local,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } \
374__OUT1(s##_p_local,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} \
375__OUTQ(s,s,x) \
376__OUTQ(s,s##_p,x)
377#endif
378
379#define __IN1(s) \
380static inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v;
381
382#define __IN2(s,s1,s2) \
383__asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
384
385#if !defined(CONFIG_MULTIQUAD) || defined(STANDALONE)
386#define __IN(s,s1,i...) \
387__IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
388__IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; }
389#else
390
391#define __IN(s,s1,i...) \
392__IN1(s##_local) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
393__IN1(s##_p_local) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } \
394__INQ(s,s) \
395__INQ(s,s##_p)
396#endif
397
398#define __INS(s) \
399static inline void ins##s(unsigned short port, void * addr, unsigned long count) \
400{ __asm__ __volatile__ ("rep ; ins" #s \
401: "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
402
403#define __OUTS(s) \
404static inline void outs##s(unsigned short port, const void * addr, unsigned long count) \
405{ __asm__ __volatile__ ("rep ; outs" #s \
406: "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
407
408#define RETURN_TYPE unsigned char
409__IN(b,"")
410#undef RETURN_TYPE
411#define RETURN_TYPE unsigned short
412__IN(w,"")
413#undef RETURN_TYPE
414#define RETURN_TYPE unsigned int
415__IN(l,"")
416#undef RETURN_TYPE
417
418__OUT(b,"b",char)
419__OUT(w,"w",short)
420__OUT(l,,int)
421
422__INS(b)
423__INS(w)
424__INS(l)
425
426__OUTS(b)
427__OUTS(w)
428__OUTS(l)
429
430#endif
431