1 /* $Id: io.h,v 1.9 2000/02/04 07:40:53 ralf Exp $
2 *
3 * This file is subject to the terms and conditions of the GNU General Public
4 * License. See the file "COPYING" in the main directory of this archive
5 * for more details.
6 *
7 * Copyright (C) 1994, 1995 Waldorf GmbH
8 * Copyright (C) 1994 - 2000 Ralf Baechle
9 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
10 */
11 #ifndef _ASM_IO_H
12 #define _ASM_IO_H
13
14 #include <linux/config.h>
15 #include <asm/addrspace.h>
16 #include <asm/page.h>
17
18 #ifdef CONFIG_SGI_IP22
19 #include <asm/sgi/io.h>
20 #endif
21
22 #ifdef CONFIG_SGI_IP27
23 #include <asm/sn/io.h>
24 #endif
25
26 extern unsigned long bus_to_baddr[256];
27
28 /*
29 * Slowdown I/O port space accesses for antique hardware.
30 */
31 #undef CONF_SLOWDOWN_IO
32
33 /*
34 * On MIPS, we have the whole physical address space mapped at all
35 * times, so "ioremap()" and "iounmap()" do not need to do anything.
36 *
37 * We cheat a bit and always return uncachable areas until we've fixed
38 * the drivers to handle caching properly.
39 */
40 extern inline void *
41 ioremap(unsigned long offset, unsigned long size)
42 {
43 return (void *) (IO_SPACE_BASE | offset);
44 }
45
46 /* This one maps high address device memory and turns off caching for that
47 * area. It's useful if some control registers are in such an area and write
48 * combining or read caching is not desirable.
49 */
50 extern inline void *
51 ioremap_nocache (unsigned long offset, unsigned long size)
52 {
53 return (void *) (IO_SPACE_BASE | offset);
54 }
55
56 extern inline void iounmap(void *addr)
57 {
58 }
59
60 /*
61 * This assumes sane hardware. The Origin is.
62 */
63 #define readb(addr) (*(volatile unsigned char *) (addr))
64 #define readw(addr) (*(volatile unsigned short *) (addr))
65 #define readl(addr) (*(volatile unsigned int *) (addr))
66
67 #define writeb(b,addr) (*(volatile unsigned char *) (addr) = (b))
68 #define writew(b,addr) (*(volatile unsigned short *) (addr) = (b))
69 #define writel(b,addr) (*(volatile unsigned int *) (addr) = (b))
70
71 #define memset_io(a,b,c) memset((void *) a,(b),(c))
72 #define memcpy_fromio(a,b,c) memcpy((a),(void *)(b),(c))
73 #define memcpy_toio(a,b,c) memcpy((void *)(a),(b),(c))
74
75 /* The ISA versions are supplied by system specific code */
76
77 /*
78 * On MIPS I/O ports are memory mapped, so we access them using normal
79 * load/store instructions. mips_io_port_base is the virtual address to
80 * which all ports are being mapped. For sake of efficiency some code
81 * assumes that this is an address that can be loaded with a single lui
82 * instruction, so the lower 16 bits must be zero. Should be true on
83 * on any sane architecture; generic code does not use this assumption.
84 */
85 extern unsigned long mips_io_port_base;
86
87 #define __SLOW_DOWN_IO \
88 __asm__ __volatile__( \
89 "sb\t$0,0x80(%0)" \
90 : : "r" (mips_io_port_base));
91
92 #ifdef CONF_SLOWDOWN_IO
93 #ifdef REALLY_SLOW_IO
94 #define SLOW_DOWN_IO { __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; __SLOW_DOWN_IO; }
95 #else
96 #define SLOW_DOWN_IO __SLOW_DOWN_IO
97 #endif
98 #else
99 #define SLOW_DOWN_IO
100 #endif
101
102 /*
103 * Change virtual addresses to physical addresses and vv.
104 * These are trivial on the 1:1 Linux/MIPS mapping
105 */
106 extern inline unsigned long virt_to_phys(volatile void * address)
107 {
108 return (unsigned long)address - PAGE_OFFSET;
109 }
110
111 extern inline void * phys_to_virt(unsigned long address)
112 {
113 return (void *)(address + PAGE_OFFSET);
114 }
115
116 /*
117 * isa_slot_offset is the address where E(ISA) busaddress 0 is is mapped
118 * for the processor. This implies the assumption that there is only
119 * one of these busses.
120 */
121 extern unsigned long isa_slot_offset;
122
123 /*
124 * We don't have csum_partial_copy_fromio() yet, so we cheat here and
125 * just copy it. The net code will then do the checksum later.
126 */
127 #define eth_io_copy_and_sum(skb,src,len,unused) memcpy_fromio((skb)->data,(src),(len))
128
129 static inline int
130 check_signature(unsigned long io_addr, const unsigned char *signature,
131 int length)
132 {
133 int retval = 0;
134 do {
135 if (readb(io_addr) != *signature)
136 goto out;
137 io_addr++;
138 signature++;
139 length--;
140 } while (length);
141 retval = 1;
142 out:
143 return retval;
144 }
145
146 /*
147 * Talk about misusing macros..
148 */
149
150 #define __OUT1(s) \
151 extern inline void __out##s(unsigned int value, unsigned long port) {
152
153 #define __OUT2(m) \
154 __asm__ __volatile__ ("s" #m "\t%0,%1(%2)"
155
156 #define __OUT(m,s) \
157 __OUT1(s) __OUT2(m) : : "r" (value), "i" (0), "r" (mips_io_port_base+port)); } \
158 __OUT1(s##c) __OUT2(m) : : "r" (value), "ir" (port), "r" (mips_io_port_base)); } \
159 __OUT1(s##_p) __OUT2(m) : : "r" (value), "i" (0), "r" (mips_io_port_base+port)); \
160 SLOW_DOWN_IO; } \
161 __OUT1(s##c_p) __OUT2(m) : : "r" (value), "ir" (port), "r" (mips_io_port_base)); \
162 SLOW_DOWN_IO; }
163
164 #define __IN1(t,s) \
165 extern __inline__ t __in##s(unsigned long port) { t _v;
166
167 /*
168 * Required nops will be inserted by the assembler
169 */
170 #define __IN2(m) \
171 __asm__ __volatile__ ("l" #m "\t%0,%1(%2)"
172
173 #define __IN(t,m,s) \
174 __IN1(t,s) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); return _v; } \
175 __IN1(t,s##c) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); return _v; } \
176 __IN1(t,s##_p) __IN2(m) : "=r" (_v) : "i" (0), "r" (mips_io_port_base+port)); SLOW_DOWN_IO; return _v; } \
177 __IN1(t,s##c_p) __IN2(m) : "=r" (_v) : "ir" (port), "r" (mips_io_port_base)); SLOW_DOWN_IO; return _v; }
178
179 #define __INS1(s) \
180 extern inline void __ins##s(unsigned long port, void * addr, unsigned long count) {
181
182 #define __INS2(m) \
183 if (count) \
184 __asm__ __volatile__ ( \
185 ".set\tnoreorder\n\t" \
186 ".set\tnoat\n" \
187 "1:\tl" #m "\t$1, %4(%5)\n\t" \
188 "dsubiu\t%1, 1\n\t" \
189 "s" #m "\t$1,(%0)\n\t" \
190 "bnez\t%1, 1b\n\t" \
191 "daddiu\t%0, %6\n\t" \
192 ".set\tat\n\t" \
193 ".set\treorder"
194
195 #define __INS(m,s,i) \
196 __INS1(s) __INS2(m) \
197 : "=r" (addr), "=r" (count) \
198 : "" (addr), "1" (count), "i" (0), "r" (mips_io_port_base+port), "I" (i) \
199 : "$1");} \
200 __INS1(s##c) __INS2(m) \
201 : "=r" (addr), "=r" (count) \
202 : "" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), "I" (i) \
203 : "$1");}
204
205 #define __OUTS1(s) \
206 extern inline void __outs##s(unsigned long port, const void * addr, unsigned long count) {
207
208 #define __OUTS2(m) \
209 if (count) \
210 __asm__ __volatile__ ( \
211 ".set\tnoreorder\n\t" \
212 ".set\tnoat\n" \
213 "1:\tl" #m "\t$1, (%0)\n\t" \
214 "dsubu\t%1, 1\n\t" \
215 "s" #m "\t$1, %4(%5)\n\t" \
216 "bnez\t%1, 1b\n\t" \
217 "daddiu\t%0, %6\n\t" \
218 ".set\tat\n\t" \
219 ".set\treorder"
220
221 #define __OUTS(m,s,i) \
222 __OUTS1(s) __OUTS2(m) \
223 : "=r" (addr), "=r" (count) \
224 : "" (addr), "1" (count), "i" (0), "r" (mips_io_port_base+port), "I" (i) \
225 : "$1");} \
226 __OUTS1(s##c) __OUTS2(m) \
227 : "=r" (addr), "=r" (count) \
228 : "" (addr), "1" (count), "ir" (port), "r" (mips_io_port_base), "I" (i) \
229 : "$1");}
230
231 __IN(unsigned char,b,b)
232 __IN(unsigned short,h,w)
233 __IN(unsigned int,w,l)
234
235 __OUT(b,b)
236 __OUT(h,w)
237 __OUT(w,l)
238
239 __INS(b,b,1)
240 __INS(h,w,2)
241 __INS(w,l,4)
242
243 __OUTS(b,b,1)
244 __OUTS(h,w,2)
245 __OUTS(w,l,4)
246
247 /*
248 * Note that due to the way __builtin_constant_p() works, you
249 * - can't use it inside an inline function (it will never be true)
250 * - you don't have to worry about side effects within the __builtin..
251 */
252 #define outb(val,port) \
253 ((__builtin_constant_p((port)^(3)) && ((port)^(3)) < 32768) ? \
254 __outbc((val),(port)^(3)) : \
255 __outb((val),(port)^(3)))
256
257 #define inb(port) \
258 ((__builtin_constant_p((port)^(3)) && ((port)^(3)) < 32768) ? \
259 __inbc((port)^(3)) : \
260 __inb((port)^(3)))
261
262 #define outb_p(val,port) \
263 ((__builtin_constant_p((port)^(3)) && ((port)^(3)) < 32768) ? \
264 __outbc_p((val),(port)^(3)) : \
265 __outb_p((val),(port)^(3)))
266
267 #define inb_p(port) \
268 ((__builtin_constant_p((port)^(3)) && ((port)^(3)) < 32768) ? \
269 __inbc_p((port)^(3)) : \
270 __inb_p((port)^(3)))
271
272 #define outw(val,port) \
273 ((__builtin_constant_p(((port)^(2))) && ((port)^(2)) < 32768) ? \
274 __outwc((val),((port)^(2))) : \
275 __outw((val),((port)^(2))))
276
277 #define inw(port) \
278 ((__builtin_constant_p(((port)^(2))) && ((port)^(2)) < 32768) ? \
279 __inwc((port)^(2)) : \
280 __inw((port)^(2)))
281
282 #define outw_p(val,port) \
283 ((__builtin_constant_p((port)^(2)) && ((port)^(2)) < 32768) ? \
284 __outwc_p((val),(port)^(2)) : \
285 __outw_p((val),(port)^(2)))
286
287 #define inw_p(port) \
288 ((__builtin_constant_p((port)^(2)) && ((port)^(2)) < 32768) ? \
289 __inwc_p((port)^(2)) : \
290 __inw_p((port)^(2)))
291
292 #define outl(val,port) \
293 ((__builtin_constant_p((port)) && (port) < 32768) ? \
294 __outlc((val),(port)) : \
295 __outl((val),(port)))
296
297 #define inl(port) \
298 ((__builtin_constant_p((port)) && (port) < 32768) ? \
299 __inlc(port) : \
300 __inl(port))
301
302 #define outl_p(val,port) \
303 ((__builtin_constant_p((port)) && (port) < 32768) ? \
304 __outlc_p((val),(port)) : \
305 __outl_p((val),(port)))
306
307 #define inl_p(port) \
308 ((__builtin_constant_p((port)) && (port) < 32768) ? \
309 __inlc_p(port) : \
310 __inl_p(port))
311
312
313 #define outsb(port,addr,count) \
314 ((__builtin_constant_p((port)) && (port) < 32768) ? \
315 __outsbc((port),(addr),(count)) : \
316 __outsb ((port),(addr),(count)))
317
318 #define insb(port,addr,count) \
319 ((__builtin_constant_p((port)) && (port) < 32768) ? \
320 __insbc((port),(addr),(count)) : \
321 __insb((port),(addr),(count)))
322
323 #define outsw(port,addr,count) \
324 ((__builtin_constant_p((port)) && (port) < 32768) ? \
325 __outswc((port),(addr),(count)) : \
326 __outsw ((port),(addr),(count)))
327
328 #define insw(port,addr,count) \
329 ((__builtin_constant_p((port)) && (port) < 32768) ? \
330 __inswc((port),(addr),(count)) : \
331 __insw((port),(addr),(count)))
332
333 #define outsl(port,addr,count) \
334 ((__builtin_constant_p((port)) && (port) < 32768) ? \
335 __outslc((port),(addr),(count)) : \
336 __outsl ((port),(addr),(count)))
337
338 #define insl(port,addr,count) \
339 ((__builtin_constant_p((port)) && (port) < 32768) ? \
340 __inslc((port),(addr),(count)) : \
341 __insl((port),(addr),(count)))
342
343 /*
344 * The caches on some architectures aren't dma-coherent and have need to
345 * handle this in software. There are three types of operations that
346 * can be applied to dma buffers.
347 *
348 * - dma_cache_wback_inv(start, size) makes caches and coherent by
349 * writing the content of the caches back to memory, if necessary.
350 * The function also invalidates the affected part of the caches as
351 * necessary before DMA transfers from outside to memory.
352 * - dma_cache_wback(start, size) makes caches and coherent by
353 * writing the content of the caches back to memory, if necessary.
354 * The function also invalidates the affected part of the caches as
355 * necessary before DMA transfers from outside to memory.
356 * - dma_cache_inv(start, size) invalidates the affected parts of the
357 * caches. Dirty lines of the caches may be written back or simply
358 * be discarded. This operation is necessary before dma operations
359 * to the memory.
360 */
361 #ifdef CONFIG_COHERENT_IO
362
363 /* This is for example for IP27. */
364 extern inline void dma_cache_wback_inv(unsigned long start, unsigned long size)
365 {
366 }
367
368 extern inline void dma_cache_wback(unsigned long start, unsigned long size)
369 {
370 }
371
372 extern inline void dma_cache_inv(unsigned long start, unsigned long size)
373 {
374 }
375
376 #else
377
378 extern void (*_dma_cache_wback_inv)(unsigned long start, unsigned long size);
379 extern void (*_dma_cache_wback)(unsigned long start, unsigned long size);
380 extern void (*_dma_cache_inv)(unsigned long start, unsigned long size);
381
382 #define dma_cache_wback_inv(start,size) _dma_cache_wback_inv(start,size)
383 #define dma_cache_wback(start,size) _dma_cache_wback(start,size)
384 #define dma_cache_inv(start,size) _dma_cache_inv(start,size)
385
386 #endif
387
388 #endif /* _ASM_IO_H */
389
This page was automatically generated by the
LXR engine.
Visit the LXR main site for more
information.