ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / include / asm-i386 / io.h
1 #ifndef _ASM_IO_H
2 #define _ASM_IO_H
3
4 #include <linux/config.h>
5
6 /*
7  * This file contains the definitions for the x86 IO instructions
8  * inb/inw/inl/outb/outw/outl and the "string versions" of the same
9  * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
10  * versions of the single-IO instructions (inb_p/inw_p/..).
11  *
12  * This file is not meant to be obfuscating: it's just complicated
13  * to (a) handle it all in a way that makes gcc able to optimize it
14  * as well as possible and (b) trying to avoid writing the same thing
15  * over and over again with slight variations and possibly making a
16  * mistake somewhere.
17  */
18
19 /*
20  * Thanks to James van Artsdalen for a better timing-fix than
21  * the two short jumps: using outb's to a nonexistent port seems
22  * to guarantee better timings even on fast machines.
23  *
24  * On the other hand, I'd like to be sure of a non-existent port:
25  * I feel a bit unsafe about using 0x80 (should be safe, though)
26  *
27  *              Linus
28  */
29
30  /*
31   *  Bit simplified and optimized by Jan Hubicka
32   *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999.
33   *
34   *  isa_memset_io, isa_memcpy_fromio, isa_memcpy_toio added,
35   *  isa_read[wl] and isa_write[wl] fixed
36   *  - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
37   */
38
39 #define IO_SPACE_LIMIT 0xffff
40
41 #define XQUAD_PORTIO_BASE 0xfe400000
42 #define XQUAD_PORTIO_QUAD 0x40000  /* 256k per quad. */
43
44 #ifdef __KERNEL__
45
46 #include <linux/vmalloc.h>
47
48 /**
49  *      virt_to_phys    -       map virtual addresses to physical
50  *      @address: address to remap
51  *
52  *      The returned physical address is the physical (CPU) mapping for
53  *      the memory address given. It is only valid to use this function on
54  *      addresses directly mapped or allocated via kmalloc. 
55  *
56  *      This function does not give bus mappings for DMA transfers. In
57  *      almost all conceivable cases a device driver should not be using
58  *      this function
59  */
60  
61 static inline unsigned long virt_to_phys(volatile void * address)
62 {
63         return __pa(address);
64 }
65
66 /**
67  *      phys_to_virt    -       map physical address to virtual
68  *      @address: address to remap
69  *
70  *      The returned virtual address is a current CPU mapping for
71  *      the memory address given. It is only valid to use this function on
72  *      addresses that have a kernel mapping
73  *
74  *      This function does not handle bus mappings for DMA transfers. In
75  *      almost all conceivable cases a device driver should not be using
76  *      this function
77  */
78
79 static inline void * phys_to_virt(unsigned long address)
80 {
81         return __va(address);
82 }
83
84 /*
85  * Change "struct page" to physical address.
86  */
87 #define page_to_phys(page)    ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
88
89 extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
90
91 /**
92  * ioremap     -   map bus memory into CPU space
93  * @offset:    bus address of the memory
94  * @size:      size of the resource to map
95  *
96  * ioremap performs a platform specific sequence of operations to
97  * make bus memory CPU accessible via the readb/readw/readl/writeb/
98  * writew/writel functions and the other mmio helpers. The returned
99  * address is not guaranteed to be usable directly as a virtual
100  * address. 
101  */
102
103 static inline void * ioremap (unsigned long offset, unsigned long size)
104 {
105         return __ioremap(offset, size, 0);
106 }
107
108 extern void * ioremap_nocache (unsigned long offset, unsigned long size);
109 extern void iounmap(void *addr);
110
111 /*
112  * bt_ioremap() and bt_iounmap() are for temporary early boot-time
113  * mappings, before the real ioremap() is functional.
114  * A boot-time mapping is currently limited to at most 16 pages.
115  */
116 extern void *bt_ioremap(unsigned long offset, unsigned long size);
117 extern void bt_iounmap(void *addr, unsigned long size);
118
119 /*
120  * ISA I/O bus memory addresses are 1:1 with the physical address.
121  */
122 #define isa_virt_to_bus virt_to_phys
123 #define isa_page_to_bus page_to_phys
124 #define isa_bus_to_virt phys_to_virt
125
126 /*
127  * However PCI ones are not necessarily 1:1 and therefore these interfaces
128  * are forbidden in portable PCI drivers.
129  *
130  * Allow them on x86 for legacy drivers, though.
131  */
132 #define virt_to_bus virt_to_phys
133 #define bus_to_virt phys_to_virt
134
135 /*
136  * readX/writeX() are used to access memory mapped devices. On some
137  * architectures the memory mapped IO stuff needs to be accessed
138  * differently. On the x86 architecture, we just read/write the
139  * memory location directly.
140  */
141
142 #define readb(addr) (*(volatile unsigned char *) (addr))
143 #define readw(addr) (*(volatile unsigned short *) (addr))
144 #define readl(addr) (*(volatile unsigned int *) (addr))
145 #define readb_relaxed(addr) readb(addr)
146 #define readw_relaxed(addr) readw(addr)
147 #define readl_relaxed(addr) readl(addr)
148 #define __raw_readb readb
149 #define __raw_readw readw
150 #define __raw_readl readl
151
152 #define writeb(b,addr) (*(volatile unsigned char *) (addr) = (b))
153 #define writew(b,addr) (*(volatile unsigned short *) (addr) = (b))
154 #define writel(b,addr) (*(volatile unsigned int *) (addr) = (b))
155 #define __raw_writeb writeb
156 #define __raw_writew writew
157 #define __raw_writel writel
158
159 #define memset_io(a,b,c)        memset((void *)(a),(b),(c))
160 #define memcpy_fromio(a,b,c)    __memcpy((a),(void *)(b),(c))
161 #define memcpy_toio(a,b,c)      __memcpy((void *)(a),(b),(c))
162
163 /*
164  * ISA space is 'always mapped' on a typical x86 system, no need to
165  * explicitly ioremap() it. The fact that the ISA IO space is mapped
166  * to PAGE_OFFSET is pure coincidence - it does not mean ISA values
167  * are physical addresses. The following constant pointer can be
168  * used as the IO-area pointer (it can be iounmapped as well, so the
169  * analogy with PCI is quite large):
170  */
171 #define __ISA_IO_base ((char *)(PAGE_OFFSET))
172
173 #define isa_readb(a) readb(__ISA_IO_base + (a))
174 #define isa_readw(a) readw(__ISA_IO_base + (a))
175 #define isa_readl(a) readl(__ISA_IO_base + (a))
176 #define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a))
177 #define isa_writew(w,a) writew(w,__ISA_IO_base + (a))
178 #define isa_writel(l,a) writel(l,__ISA_IO_base + (a))
179 #define isa_memset_io(a,b,c)            memset_io(__ISA_IO_base + (a),(b),(c))
180 #define isa_memcpy_fromio(a,b,c)        memcpy_fromio((a),__ISA_IO_base + (b),(c))
181 #define isa_memcpy_toio(a,b,c)          memcpy_toio(__ISA_IO_base + (a),(b),(c))
182
183
184 /*
185  * Again, i386 does not require mem IO specific function.
186  */
187
188 #define eth_io_copy_and_sum(a,b,c,d)            eth_copy_and_sum((a),(void *)(b),(c),(d))
189 #define isa_eth_io_copy_and_sum(a,b,c,d)        eth_copy_and_sum((a),(void *)(__ISA_IO_base + (b)),(c),(d))
190
191 /**
192  *      check_signature         -       find BIOS signatures
193  *      @io_addr: mmio address to check 
194  *      @signature:  signature block
195  *      @length: length of signature
196  *
197  *      Perform a signature comparison with the mmio address io_addr. This
198  *      address should have been obtained by ioremap.
199  *      Returns 1 on a match.
200  */
201  
202 static inline int check_signature(unsigned long io_addr,
203         const unsigned char *signature, int length)
204 {
205         int retval = 0;
206         do {
207                 if (readb(io_addr) != *signature)
208                         goto out;
209                 io_addr++;
210                 signature++;
211                 length--;
212         } while (length);
213         retval = 1;
214 out:
215         return retval;
216 }
217
218 /**
219  *      isa_check_signature             -       find BIOS signatures
220  *      @io_addr: mmio address to check 
221  *      @signature:  signature block
222  *      @length: length of signature
223  *
224  *      Perform a signature comparison with the ISA mmio address io_addr.
225  *      Returns 1 on a match.
226  *
227  *      This function is deprecated. New drivers should use ioremap and
228  *      check_signature.
229  */
230  
231
232 static inline int isa_check_signature(unsigned long io_addr,
233         const unsigned char *signature, int length)
234 {
235         int retval = 0;
236         do {
237                 if (isa_readb(io_addr) != *signature)
238                         goto out;
239                 io_addr++;
240                 signature++;
241                 length--;
242         } while (length);
243         retval = 1;
244 out:
245         return retval;
246 }
247
248 /*
249  *      Cache management
250  *
251  *      This needed for two cases
252  *      1. Out of order aware processors
253  *      2. Accidentally out of order processors (PPro errata #51)
254  */
255  
256 #if defined(CONFIG_X86_OOSTORE) || defined(CONFIG_X86_PPRO_FENCE)
257
258 static inline void flush_write_buffers(void)
259 {
260         __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory");
261 }
262
263 #define dma_cache_inv(_start,_size)             flush_write_buffers()
264 #define dma_cache_wback(_start,_size)           flush_write_buffers()
265 #define dma_cache_wback_inv(_start,_size)       flush_write_buffers()
266
267 #else
268
269 /* Nothing to do */
270
271 #define dma_cache_inv(_start,_size)             do { } while (0)
272 #define dma_cache_wback(_start,_size)           do { } while (0)
273 #define dma_cache_wback_inv(_start,_size)       do { } while (0)
274 #define flush_write_buffers()
275
276 #endif
277
278 #endif /* __KERNEL__ */
279
280 #ifdef SLOW_IO_BY_JUMPING
281 #define __SLOW_DOWN_IO "jmp 1f; 1: jmp 1f; 1:"
282 #else
283 #define __SLOW_DOWN_IO "outb %%al,$0x80;"
284 #endif
285
286 static inline void slow_down_io(void) {
287         __asm__ __volatile__(
288                 __SLOW_DOWN_IO
289 #ifdef REALLY_SLOW_IO
290                 __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO
291 #endif
292                 : : );
293 }
294
295 #ifdef CONFIG_X86_NUMAQ
296 extern void *xquad_portio;    /* Where the IO area was mapped */
297 #define XQUAD_PORT_ADDR(port, quad) (xquad_portio + (XQUAD_PORTIO_QUAD*quad) + port)
298 #define __BUILDIO(bwl,bw,type) \
299 static inline void out##bwl##_quad(unsigned type value, int port, int quad) { \
300         if (xquad_portio) \
301                 write##bwl(value, XQUAD_PORT_ADDR(port, quad)); \
302         else \
303                 out##bwl##_local(value, port); \
304 } \
305 static inline void out##bwl(unsigned type value, int port) { \
306         out##bwl##_quad(value, port, 0); \
307 } \
308 static inline unsigned type in##bwl##_quad(int port, int quad) { \
309         if (xquad_portio) \
310                 return read##bwl(XQUAD_PORT_ADDR(port, quad)); \
311         else \
312                 return in##bwl##_local(port); \
313 } \
314 static inline unsigned type in##bwl(int port) { \
315         return in##bwl##_quad(port, 0); \
316 }
317 #else
318 #define __BUILDIO(bwl,bw,type) \
319 static inline void out##bwl(unsigned type value, int port) { \
320         out##bwl##_local(value, port); \
321 } \
322 static inline unsigned type in##bwl(int port) { \
323         return in##bwl##_local(port); \
324 }
325 #endif
326
327
328 #define BUILDIO(bwl,bw,type) \
329 static inline void out##bwl##_local(unsigned type value, int port) { \
330         __asm__ __volatile__("out" #bwl " %" #bw "0, %w1" : : "a"(value), "Nd"(port)); \
331 } \
332 static inline unsigned type in##bwl##_local(int port) { \
333         unsigned type value; \
334         __asm__ __volatile__("in" #bwl " %w1, %" #bw "0" : "=a"(value) : "Nd"(port)); \
335         return value; \
336 } \
337 static inline void out##bwl##_local_p(unsigned type value, int port) { \
338         out##bwl##_local(value, port); \
339         slow_down_io(); \
340 } \
341 static inline unsigned type in##bwl##_local_p(int port) { \
342         unsigned type value = in##bwl##_local(port); \
343         slow_down_io(); \
344         return value; \
345 } \
346 __BUILDIO(bwl,bw,type) \
347 static inline void out##bwl##_p(unsigned type value, int port) { \
348         out##bwl(value, port); \
349         slow_down_io(); \
350 } \
351 static inline unsigned type in##bwl##_p(int port) { \
352         unsigned type value = in##bwl(port); \
353         slow_down_io(); \
354         return value; \
355 } \
356 static inline void outs##bwl(int port, const void *addr, unsigned long count) { \
357         __asm__ __volatile__("rep; outs" #bwl : "+S"(addr), "+c"(count) : "d"(port)); \
358 } \
359 static inline void ins##bwl(int port, void *addr, unsigned long count) { \
360         __asm__ __volatile__("rep; ins" #bwl : "+D"(addr), "+c"(count) : "d"(port)); \
361 }
362
363 BUILDIO(b,b,char)
364 BUILDIO(w,w,short)
365 BUILDIO(l,,int)
366
367 #endif