File: /usr/src/linux/include/asm-sparc64/io.h

1     /* $Id: io.h,v 1.36 2000/09/17 05:12:00 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     /* Different PCI controllers we support have their PCI MEM space
22      * mapped to an either 2GB (Psycho) or 4GB (Sabre) aligned area,
23      * so need to chop off the top 33 or 32 bits.
24      */
25     extern unsigned long pci_memspace_mask;
26     
27     #define bus_dvma_to_mem(__vaddr) ((__vaddr) & pci_memspace_mask)
28     
29     extern __inline__ unsigned int inb(unsigned long addr)
30     {
31     	unsigned int ret;
32     
33     	__asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_inb */"
34     			     : "=r" (ret)
35     			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
36     
37     	return ret;
38     }
39     
40     extern __inline__ unsigned int inw(unsigned long addr)
41     {
42     	unsigned int ret;
43     
44     	__asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_inw */"
45     			     : "=r" (ret)
46     			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
47     
48     	return ret;
49     }
50     
51     extern __inline__ unsigned int inl(unsigned long addr)
52     {
53     	unsigned int ret;
54     
55     	__asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_inl */"
56     			     : "=r" (ret)
57     			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
58     
59     	return ret;
60     }
61     
62     extern __inline__ void outb(unsigned char b, unsigned long addr)
63     {
64     	__asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_outb */"
65     			     : /* no outputs */
66     			     : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
67     }
68     
69     extern __inline__ void outw(unsigned short w, unsigned long addr)
70     {
71     	__asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_outw */"
72     			     : /* no outputs */
73     			     : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
74     }
75     
76     extern __inline__ void outl(unsigned int l, unsigned long addr)
77     {
78     	__asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_outl */"
79     			     : /* no outputs */
80     			     : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
81     }
82     
83     #define inb_p inb
84     #define outb_p outb
85     #define inw_p inw
86     #define outw_p outw
87     #define inl_p inl
88     #define outl_p outl
89     
90     extern void outsb(unsigned long addr, const void *src, unsigned long count);
91     extern void outsw(unsigned long addr, const void *src, unsigned long count);
92     extern void outsl(unsigned long addr, const void *src, unsigned long count);
93     extern void insb(unsigned long addr, void *dst, unsigned long count);
94     extern void insw(unsigned long addr, void *dst, unsigned long count);
95     extern void insl(unsigned long addr, void *dst, unsigned long count);
96     
97     /* Memory functions, same as I/O accesses on Ultra. */
98     extern __inline__ unsigned int _readb(unsigned long addr)
99     {
100     	unsigned int ret;
101     
102     	__asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_readb */"
103     			     : "=r" (ret)
104     			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
105     
106     	return ret;
107     }
108     
109     extern __inline__ unsigned int _readw(unsigned long addr)
110     {
111     	unsigned int ret;
112     
113     	__asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_readw */"
114     			     : "=r" (ret)
115     			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
116     
117     	return ret;
118     }
119     
120     extern __inline__ unsigned int _readl(unsigned long addr)
121     {
122     	unsigned int ret;
123     
124     	__asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_readl */"
125     			     : "=r" (ret)
126     			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
127     
128     	return ret;
129     }
130     
131     extern __inline__ void _writeb(unsigned char b, unsigned long addr)
132     {
133     	__asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_writeb */"
134     			     : /* no outputs */
135     			     : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
136     }
137     
138     extern __inline__ void _writew(unsigned short w, unsigned long addr)
139     {
140     	__asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_writew */"
141     			     : /* no outputs */
142     			     : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
143     }
144     
145     extern __inline__ void _writel(unsigned int l, unsigned long addr)
146     {
147     	__asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_writel */"
148     			     : /* no outputs */
149     			     : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E_L));
150     }
151     
152     #define readb(__addr)		(_readb((unsigned long)(__addr)))
153     #define readw(__addr)		(_readw((unsigned long)(__addr)))
154     #define readl(__addr)		(_readl((unsigned long)(__addr)))
155     #define writeb(__b, __addr)	(_writeb((__b), (unsigned long)(__addr)))
156     #define writew(__w, __addr)	(_writew((__w), (unsigned long)(__addr)))
157     #define writel(__l, __addr)	(_writel((__l), (unsigned long)(__addr)))
158     
159     /* Now versions without byte-swapping. */
160     extern __inline__ unsigned int _raw_readb(unsigned long addr)
161     {
162     	unsigned int ret;
163     
164     	__asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_raw_readb */"
165     			     : "=r" (ret)
166     			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
167     
168     	return ret;
169     }
170     
171     extern __inline__ unsigned int _raw_readw(unsigned long addr)
172     {
173     	unsigned int ret;
174     
175     	__asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_raw_readw */"
176     			     : "=r" (ret)
177     			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
178     
179     	return ret;
180     }
181     
182     extern __inline__ unsigned int _raw_readl(unsigned long addr)
183     {
184     	unsigned int ret;
185     
186     	__asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_raw_readl */"
187     			     : "=r" (ret)
188     			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
189     
190     	return ret;
191     }
192     
193     extern __inline__ void _raw_writeb(unsigned char b, unsigned long addr)
194     {
195     	__asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_raw_writeb */"
196     			     : /* no outputs */
197     			     : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
198     }
199     
200     extern __inline__ void _raw_writew(unsigned short w, unsigned long addr)
201     {
202     	__asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_raw_writew */"
203     			     : /* no outputs */
204     			     : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
205     }
206     
207     extern __inline__ void _raw_writel(unsigned int l, unsigned long addr)
208     {
209     	__asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_raw_writel */"
210     			     : /* no outputs */
211     			     : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
212     }
213     
214     #define __raw_readb(__addr)		(_raw_readb((unsigned long)(__addr)))
215     #define __raw_readw(__addr)		(_raw_readw((unsigned long)(__addr)))
216     #define __raw_readl(__addr)		(_raw_readl((unsigned long)(__addr)))
217     #define __raw_writeb(__b, __addr)	(_raw_writeb((__b), (unsigned long)(__addr)))
218     #define __raw_writew(__w, __addr)	(_raw_writew((__w), (unsigned long)(__addr)))
219     #define __raw_writel(__l, __addr)	(_raw_writel((__l), (unsigned long)(__addr)))
220     
221     /* Valid I/O Space regions are anywhere, because each PCI bus supported
222      * can live in an arbitrary area of the physical address range.
223      */
224     #define IO_SPACE_LIMIT 0xffffffffffffffffUL
225     
226     /* Now, SBUS variants, only difference from PCI is that we do
227      * not use little-endian ASIs.
228      */
229     extern __inline__ unsigned int _sbus_readb(unsigned long addr)
230     {
231     	unsigned int ret;
232     
233     	__asm__ __volatile__("lduba\t[%1] %2, %0\t/* sbus_readb */"
234     			     : "=r" (ret)
235     			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
236     
237     	return ret;
238     }
239     
240     extern __inline__ unsigned int _sbus_readw(unsigned long addr)
241     {
242     	unsigned int ret;
243     
244     	__asm__ __volatile__("lduha\t[%1] %2, %0\t/* sbus_readw */"
245     			     : "=r" (ret)
246     			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
247     
248     	return ret;
249     }
250     
251     extern __inline__ unsigned int _sbus_readl(unsigned long addr)
252     {
253     	unsigned int ret;
254     
255     	__asm__ __volatile__("lduwa\t[%1] %2, %0\t/* sbus_readl */"
256     			     : "=r" (ret)
257     			     : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
258     
259     	return ret;
260     }
261     
262     extern __inline__ void _sbus_writeb(unsigned char b, unsigned long addr)
263     {
264     	__asm__ __volatile__("stba\t%r0, [%1] %2\t/* sbus_writeb */"
265     			     : /* no outputs */
266     			     : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
267     }
268     
269     extern __inline__ void _sbus_writew(unsigned short w, unsigned long addr)
270     {
271     	__asm__ __volatile__("stha\t%r0, [%1] %2\t/* sbus_writew */"
272     			     : /* no outputs */
273     			     : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
274     }
275     
276     extern __inline__ void _sbus_writel(unsigned int l, unsigned long addr)
277     {
278     	__asm__ __volatile__("stwa\t%r0, [%1] %2\t/* sbus_writel */"
279     			     : /* no outputs */
280     			     : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E));
281     }
282     
283     #define sbus_readb(__addr)		(_sbus_readb((unsigned long)(__addr)))
284     #define sbus_readw(__addr)		(_sbus_readw((unsigned long)(__addr)))
285     #define sbus_readl(__addr)		(_sbus_readl((unsigned long)(__addr)))
286     #define sbus_writeb(__b, __addr)	(_sbus_writeb((__b), (unsigned long)(__addr)))
287     #define sbus_writew(__w, __addr)	(_sbus_writew((__w), (unsigned long)(__addr)))
288     #define sbus_writel(__l, __addr)	(_sbus_writel((__l), (unsigned long)(__addr)))
289     
290     static inline void *_sbus_memset_io(unsigned long dst, int c, __kernel_size_t n)
291     {
292     	while(n--) {
293     		sbus_writeb(c, dst);
294     		dst++;
295     	}
296     	return (void *) dst;
297     }
298     
299     #define sbus_memset_io(d,c,sz)	\
300     	_sbus_memset_io((unsigned long)d,(int)c,(__kernel_size_t)sz)
301     
302     static inline void *
303     _memset_io(void *dst, int c, __kernel_size_t n)
304     {
305     	char *d = dst;
306     
307     	while (n--) {
308     		writeb(c, d);
309     		d++;
310     	}
311     
312     	return dst;
313     }
314     
315     #define memset_io(d,c,sz)	\
316     	_memset_io((void *)d,(int)c,(__kernel_size_t)sz)
317     
318     static inline void *
319     _memcpy_fromio(void *dst, unsigned long src, __kernel_size_t n)
320     {
321     	char *d = dst;
322     
323     	while (n--) {
324     		char tmp = readb(src);
325     		*d++ = tmp;
326     		src++;
327     	}
328     
329     	return dst;
330     }
331     
332     #define memcpy_fromio(d,s,sz)	\
333     	_memcpy_fromio((void *)d,(unsigned long)s,(__kernel_size_t)sz)
334     
335     static inline void *
336     _memcpy_toio(unsigned long dst, const void *src, __kernel_size_t n)
337     {
338     	const char *s = src;
339     	unsigned long d = dst;
340     
341     	while (n--) {
342     		char tmp = *s++;
343     		writeb(tmp, d);
344     		d++;
345     	}
346     	return (void *)dst;
347     }
348     
349     #define memcpy_toio(d,s,sz)	\
350     	_memcpy_toio((unsigned long)d,(const void *)s,(__kernel_size_t)sz)
351     
352     static inline int check_signature(unsigned long io_addr,
353     				  const unsigned char *signature,
354     				  int length)
355     {
356     	int retval = 0;
357     	do {
358     		if (readb(io_addr++) != *signature++)
359     			goto out;
360     	} while (--length);
361     	retval = 1;
362     out:
363     	return retval;
364     }
365     
366     #ifdef __KERNEL__
367     
368     /* On sparc64 we have the whole physical IO address space accessible
369      * using physically addressed loads and stores, so this does nothing.
370      */
371     #define ioremap(__offset, __size)	((void *)(__offset))
372     #define ioremap_nocache(X,Y)		ioremap((X),(Y))
373     #define iounmap(__addr)			do { } while(0)
374     
375     /* Similarly for SBUS. */
376     #define sbus_ioremap(__res, __offset, __size, __name) \
377     ({	unsigned long __ret; \
378     	__ret  = (__res)->start + (((__res)->flags & 0x1ffUL) << 32UL); \
379     	__ret += (unsigned long) (__offset); \
380     	if (! request_region((__ret), (__size), (__name))) \
381     		__ret = 0UL; \
382     	__ret; \
383     })
384     
385     #define sbus_iounmap(__addr, __size)	\
386     	release_region((__addr), (__size))
387     
388     /* Nothing to do */
389     
390     #define dma_cache_inv(_start,_size)		do { } while (0)
391     #define dma_cache_wback(_start,_size)		do { } while (0)
392     #define dma_cache_wback_inv(_start,_size)	do { } while (0)
393     
394     #endif
395     
396     #endif /* !(__SPARC64_IO_H) */
397