ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / include / asm-sparc64 / io.h
1 /* $Id: io.h,v 1.47 2001/12/13 10:36:02 davem Exp $ */
2 #ifndef __SPARC64_IO_H
3 #define __SPARC64_IO_H
4
5 #include <linux/kernel.h>
6 #include <linux/types.h>
7
8 #include <asm/page.h>      /* IO address mapping routines need this */
9 #include <asm/system.h>
10 #include <asm/asi.h>
11
12 /* PC crapola... */
13 #define __SLOW_DOWN_IO  do { } while (0)
14 #define SLOW_DOWN_IO    do { } while (0)
15
16 extern unsigned long virt_to_bus_not_defined_use_pci_map(volatile void *addr);
17 #define virt_to_bus virt_to_bus_not_defined_use_pci_map
18 extern unsigned long bus_to_virt_not_defined_use_pci_map(volatile void *addr);
19 #define bus_to_virt bus_to_virt_not_defined_use_pci_map
20
21 /* BIO layer definitions. */
22 extern unsigned long phys_base, kern_base, kern_size;
23 #define page_to_phys(page)      ((((page) - mem_map) << PAGE_SHIFT)+phys_base)
24 #define BIO_VMERGE_BOUNDARY     8192
25
26 /* Different PCI controllers we support have their PCI MEM space
27  * mapped to an either 2GB (Psycho) or 4GB (Sabre) aligned area,
28  * so need to chop off the top 33 or 32 bits.
29  */
30 extern unsigned long pci_memspace_mask;
31
32 #define bus_dvma_to_mem(__vaddr) ((__vaddr) & pci_memspace_mask)
33
34 static __inline__ u8 _inb(unsigned long addr)
35 {
36         u8 ret;
37
38         __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_inb */"
39                              : "=r" (ret)
40                              : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
41
42         return ret;
43 }
44
45 static __inline__ u16 _inw(unsigned long addr)
46 {
47         u16 ret;
48
49         __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_inw */"
50                              : "=r" (ret)
51                              : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
52
53         return ret;
54 }
55
56 static __inline__ u32 _inl(unsigned long addr)
57 {
58         u32 ret;
59
60         __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_inl */"
61                              : "=r" (ret)
62                              : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
63
64         return ret;
65 }
66
67 static __inline__ void _outb(u8 b, unsigned long addr)
68 {
69         __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_outb */"
70                              : /* no outputs */
71                              : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
72 }
73
74 static __inline__ void _outw(u16 w, unsigned long addr)
75 {
76         __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_outw */"
77                              : /* no outputs */
78                              : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
79 }
80
81 static __inline__ void _outl(u32 l, unsigned long addr)
82 {
83         __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_outl */"
84                              : /* no outputs */
85                              : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
86 }
87
88 #define inb(__addr)             (_inb((unsigned long)(__addr)))
89 #define inw(__addr)             (_inw((unsigned long)(__addr)))
90 #define inl(__addr)             (_inl((unsigned long)(__addr)))
91 #define outb(__b, __addr)       (_outb((u8)(__b), (unsigned long)(__addr)))
92 #define outw(__w, __addr)       (_outw((u16)(__w), (unsigned long)(__addr)))
93 #define outl(__l, __addr)       (_outl((u32)(__l), (unsigned long)(__addr)))
94
95 #define inb_p(__addr)           inb(__addr)
96 #define outb_p(__b, __addr)     outb(__b, __addr)
97 #define inw_p(__addr)           inw(__addr)
98 #define outw_p(__w, __addr)     outw(__w, __addr)
99 #define inl_p(__addr)           inl(__addr)
100 #define outl_p(__l, __addr)     outl(__l, __addr)
101
102 extern void outsb(unsigned long addr, const void *src, unsigned long count);
103 extern void outsw(unsigned long addr, const void *src, unsigned long count);
104 extern void outsl(unsigned long addr, const void *src, unsigned long count);
105 extern void insb(unsigned long addr, void *dst, unsigned long count);
106 extern void insw(unsigned long addr, void *dst, unsigned long count);
107 extern void insl(unsigned long addr, void *dst, unsigned long count);
108
109 /* Memory functions, same as I/O accesses on Ultra. */
110 static __inline__ u8 _readb(unsigned long addr)
111 {
112         u8 ret;
113
114         __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_readb */"
115                              : "=r" (ret)
116                              : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
117
118         return ret;
119 }
120
121 static __inline__ u16 _readw(unsigned long addr)
122 {
123         u16 ret;
124
125         __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_readw */"
126                              : "=r" (ret)
127                              : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
128
129         return ret;
130 }
131
132 static __inline__ u32 _readl(unsigned long addr)
133 {
134         u32 ret;
135
136         __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_readl */"
137                              : "=r" (ret)
138                              : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
139
140         return ret;
141 }
142
143 static __inline__ u64 _readq(unsigned long addr)
144 {
145         u64 ret;
146
147         __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_readq */"
148                              : "=r" (ret)
149                              : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
150
151         return ret;
152 }
153
154 static __inline__ void _writeb(u8 b, unsigned long addr)
155 {
156         __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_writeb */"
157                              : /* no outputs */
158                              : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
159 }
160
161 static __inline__ void _writew(u16 w, unsigned long addr)
162 {
163         __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_writew */"
164                              : /* no outputs */
165                              : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
166 }
167
168 static __inline__ void _writel(u32 l, unsigned long addr)
169 {
170         __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */"
171                              : /* no outputs */
172                              : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
173 }
174
175 static __inline__ void _writeq(u64 q, unsigned long addr)
176 {
177         __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_writeq */"
178                              : /* no outputs */
179                              : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
180 }
181
182 #define readb(__addr)           (_readb((unsigned long)(__addr)))
183 #define readw(__addr)           (_readw((unsigned long)(__addr)))
184 #define readl(__addr)           (_readl((unsigned long)(__addr)))
185 #define readq(__addr)           (_readq((unsigned long)(__addr)))
186 #define readb_relaxed(a)        readb(a)
187 #define readw_relaxed(a)        readw(a)
188 #define readl_relaxed(a)        readl(a)
189 #define readq_relaxed(a)        readq(a)
190 #define writeb(__b, __addr)     (_writeb((u8)(__b), (unsigned long)(__addr)))
191 #define writew(__w, __addr)     (_writew((u16)(__w), (unsigned long)(__addr)))
192 #define writel(__l, __addr)     (_writel((u32)(__l), (unsigned long)(__addr)))
193 #define writeq(__q, __addr)     (_writeq((u64)(__q), (unsigned long)(__addr)))
194
195 /* Now versions without byte-swapping. */
196 static __inline__ u8 _raw_readb(unsigned long addr)
197 {
198         u8 ret;
199
200         __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_raw_readb */"
201                              : "=r" (ret)
202                              : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
203
204         return ret;
205 }
206
207 static __inline__ u16 _raw_readw(unsigned long addr)
208 {
209         u16 ret;
210
211         __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_raw_readw */"
212                              : "=r" (ret)
213                              : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
214
215         return ret;
216 }
217
218 static __inline__ u32 _raw_readl(unsigned long addr)
219 {
220         u32 ret;
221
222         __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_raw_readl */"
223                              : "=r" (ret)
224                              : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
225
226         return ret;
227 }
228
229 static __inline__ u64 _raw_readq(unsigned long addr)
230 {
231         u64 ret;
232
233         __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* pci_raw_readq */"
234                              : "=r" (ret)
235                              : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
236
237         return ret;
238 }
239
240 static __inline__ void _raw_writeb(u8 b, unsigned long addr)
241 {
242         __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_raw_writeb */"
243                              : /* no outputs */
244                              : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
245 }
246
247 static __inline__ void _raw_writew(u16 w, unsigned long addr)
248 {
249         __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_raw_writew */"
250                              : /* no outputs */
251                              : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
252 }
253
254 static __inline__ void _raw_writel(u32 l, unsigned long addr)
255 {
256         __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_raw_writel */"
257                              : /* no outputs */
258                              : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
259 }
260
261 static __inline__ void _raw_writeq(u64 q, unsigned long addr)
262 {
263         __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* pci_raw_writeq */"
264                              : /* no outputs */
265                              : "Jr" (q), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
266 }
267
268 #define __raw_readb(__addr)             (_raw_readb((unsigned long)(__addr)))
269 #define __raw_readw(__addr)             (_raw_readw((unsigned long)(__addr)))
270 #define __raw_readl(__addr)             (_raw_readl((unsigned long)(__addr)))
271 #define __raw_readq(__addr)             (_raw_readq((unsigned long)(__addr)))
272 #define __raw_writeb(__b, __addr)       (_raw_writeb((u8)(__b), (unsigned long)(__addr)))
273 #define __raw_writew(__w, __addr)       (_raw_writew((u16)(__w), (unsigned long)(__addr)))
274 #define __raw_writel(__l, __addr)       (_raw_writel((u32)(__l), (unsigned long)(__addr)))
275 #define __raw_writeq(__q, __addr)       (_raw_writeq((u64)(__q), (unsigned long)(__addr)))
276
277 /* Valid I/O Space regions are anywhere, because each PCI bus supported
278  * can live in an arbitrary area of the physical address range.
279  */
280 #define IO_SPACE_LIMIT 0xffffffffffffffffUL
281
282 /* Now, SBUS variants, only difference from PCI is that we do
283  * not use little-endian ASIs.
284  */
285 static __inline__ u8 _sbus_readb(unsigned long addr)
286 {
287         u8 ret;
288
289         __asm__ __volatile__("lduba\t[%1] %2, %0\t/* sbus_readb */"
290                              : "=r" (ret)
291                              : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
292
293         return ret;
294 }
295
296 static __inline__ u16 _sbus_readw(unsigned long addr)
297 {
298         u16 ret;
299
300         __asm__ __volatile__("lduha\t[%1] %2, %0\t/* sbus_readw */"
301                              : "=r" (ret)
302                              : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
303
304         return ret;
305 }
306
307 static __inline__ u32 _sbus_readl(unsigned long addr)
308 {
309         u32 ret;
310
311         __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* sbus_readl */"
312                              : "=r" (ret)
313                              : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
314
315         return ret;
316 }
317
318 static __inline__ u64 _sbus_readq(unsigned long addr)
319 {
320         u64 ret;
321
322         __asm__ __volatile__("ldxa\t[%1] %2, %0\t/* sbus_readq */"
323                              : "=r" (ret)
324                              : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
325
326         return ret;
327 }
328
329 static __inline__ void _sbus_writeb(u8 b, unsigned long addr)
330 {
331         __asm__ __volatile__("stba\t%r0, [%1] %2\t/* sbus_writeb */"
332                              : /* no outputs */
333                              : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
334 }
335
336 static __inline__ void _sbus_writew(u16 w, unsigned long addr)
337 {
338         __asm__ __volatile__("stha\t%r0, [%1] %2\t/* sbus_writew */"
339                              : /* no outputs */
340                              : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
341 }
342
343 static __inline__ void _sbus_writel(u32 l, unsigned long addr)
344 {
345         __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* sbus_writel */"
346                              : /* no outputs */
347                              : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
348 }
349
350 static __inline__ void _sbus_writeq(u64 l, unsigned long addr)
351 {
352         __asm__ __volatile__("stxa\t%r0, [%1] %2\t/* sbus_writeq */"
353                              : /* no outputs */
354                              : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
355 }
356
357 #define sbus_readb(__addr)              (_sbus_readb((unsigned long)(__addr)))
358 #define sbus_readw(__addr)              (_sbus_readw((unsigned long)(__addr)))
359 #define sbus_readl(__addr)              (_sbus_readl((unsigned long)(__addr)))
360 #define sbus_readq(__addr)              (_sbus_readq((unsigned long)(__addr)))
361 #define sbus_writeb(__b, __addr)        (_sbus_writeb((__b), (unsigned long)(__addr)))
362 #define sbus_writew(__w, __addr)        (_sbus_writew((__w), (unsigned long)(__addr)))
363 #define sbus_writel(__l, __addr)        (_sbus_writel((__l), (unsigned long)(__addr)))
364 #define sbus_writeq(__l, __addr)        (_sbus_writeq((__l), (unsigned long)(__addr)))
365
366 static inline void *_sbus_memset_io(unsigned long dst, int c, __kernel_size_t n)
367 {
368         while(n--) {
369                 sbus_writeb(c, dst);
370                 dst++;
371         }
372         return (void *) dst;
373 }
374
375 #define sbus_memset_io(d,c,sz)  \
376         _sbus_memset_io((unsigned long)d,(int)c,(__kernel_size_t)sz)
377
378 static inline void *
379 _memset_io(void *dst, int c, __kernel_size_t n)
380 {
381         char *d = dst;
382
383         while (n--) {
384                 writeb(c, d);
385                 d++;
386         }
387
388         return dst;
389 }
390
391 #define memset_io(d,c,sz)       \
392         _memset_io((void *)d,(int)c,(__kernel_size_t)sz)
393
394 static inline void *
395 _memcpy_fromio(void *dst, unsigned long src, __kernel_size_t n)
396 {
397         char *d = dst;
398
399         while (n--) {
400                 char tmp = readb(src);
401                 *d++ = tmp;
402                 src++;
403         }
404
405         return dst;
406 }
407
408 #define memcpy_fromio(d,s,sz)   \
409         _memcpy_fromio((void *)d,(unsigned long)s,(__kernel_size_t)sz)
410
411 static inline void *
412 _memcpy_toio(unsigned long dst, const void *src, __kernel_size_t n)
413 {
414         const char *s = src;
415         unsigned long d = dst;
416
417         while (n--) {
418                 char tmp = *s++;
419                 writeb(tmp, d);
420                 d++;
421         }
422         return (void *)dst;
423 }
424
425 #define memcpy_toio(d,s,sz)     \
426         _memcpy_toio((unsigned long)d,(const void *)s,(__kernel_size_t)sz)
427
428 static inline int check_signature(unsigned long io_addr,
429                                   const unsigned char *signature,
430                                   int length)
431 {
432         int retval = 0;
433         do {
434                 if (readb(io_addr++) != *signature++)
435                         goto out;
436         } while (--length);
437         retval = 1;
438 out:
439         return retval;
440 }
441
442 #ifdef __KERNEL__
443
444 /* On sparc64 we have the whole physical IO address space accessible
445  * using physically addressed loads and stores, so this does nothing.
446  */
447 #define ioremap(__offset, __size)       ((void *)(__offset))
448 #define ioremap_nocache(X,Y)            ioremap((X),(Y))
449 #define iounmap(__addr)                 do { (void)(__addr); } while(0)
450
451 /* Similarly for SBUS. */
452 #define sbus_ioremap(__res, __offset, __size, __name) \
453 ({      unsigned long __ret; \
454         __ret  = (__res)->start + (((__res)->flags & 0x1ffUL) << 32UL); \
455         __ret += (unsigned long) (__offset); \
456         if (! request_region((__ret), (__size), (__name))) \
457                 __ret = 0UL; \
458         __ret; \
459 })
460
461 #define sbus_iounmap(__addr, __size)    \
462         release_region((__addr), (__size))
463
464 /* Nothing to do */
465
466 #define dma_cache_inv(_start,_size)             do { } while (0)
467 #define dma_cache_wback(_start,_size)           do { } while (0)
468 #define dma_cache_wback_inv(_start,_size)       do { } while (0)
469
470 #endif
471
472 #endif /* !(__SPARC64_IO_H) */