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

1     /*
2      * $Id: io.h,v 1.28 2000/09/17 05:12:00 davem Exp $
3      */
4     #ifndef __SPARC_IO_H
5     #define __SPARC_IO_H
6     
7     #include <linux/kernel.h>
8     #include <linux/types.h>
9     #include <linux/ioport.h>  /* struct resource */
10     
11     #include <asm/page.h>      /* IO address mapping routines need this */
12     #include <asm/system.h>
13     
14     #define virt_to_bus virt_to_phys
15     #define bus_to_virt phys_to_virt
16     
17     extern __inline__ unsigned  flip_dword (unsigned d) {
18     	return ((d&0xff)<<24) | (((d>>8)&0xff)<<16) | (((d>>16)&0xff)<<8)| ((d>>24)&0xff);
19     }
20     
21     extern __inline__ unsigned short flip_word (unsigned short d) {
22     	return ((d&0xff) << 8) | ((d>>8)&0xff);
23     }
24     
25     /*
26      * Memory mapped I/O to PCI
27      */
28     extern __inline__ unsigned long readb(unsigned long addr) {
29     	return *(volatile unsigned char*)addr;
30     }
31     
32     extern __inline__ unsigned long readw(unsigned long addr) {
33     	return flip_word(*(volatile unsigned short*)addr);
34     }
35     
36     extern __inline__ unsigned long readl(unsigned long addr) {
37     	return flip_dword(*(volatile unsigned long*)addr);
38     }
39     
40     extern __inline__ void writeb(unsigned char b, unsigned long addr) {
41     	*(volatile unsigned char*)addr = b;
42     }
43     
44     extern __inline__ void writew(unsigned short b, unsigned long addr) {
45     	*(volatile unsigned short*)addr = flip_word(b);
46     }
47     
48     extern __inline__ void writel(unsigned int b, unsigned long addr) {
49     	*(volatile unsigned long*)addr = flip_dword(b);
50     }
51     
52     /* Now the 'raw' versions. */
53     extern __inline__ unsigned long __raw_readb(unsigned long addr) {
54     	return *(volatile unsigned char*)addr;
55     }
56     
57     extern __inline__ unsigned long __raw_readw(unsigned long addr) {
58     	return *(volatile unsigned short*)addr;
59     }
60     
61     extern __inline__ unsigned long __raw_readl(unsigned long addr) {
62     	return *(volatile unsigned long*)addr;
63     }
64     
65     extern __inline__ void __raw_writeb(unsigned char b, unsigned long addr) {
66     	*(volatile unsigned char*)addr = b;
67     }
68     
69     extern __inline__ void __raw_writew(unsigned short b, unsigned long addr) {
70     	*(volatile unsigned short*)addr = b;
71     }
72     
73     extern __inline__ void __raw_writel(unsigned int b, unsigned long addr) {
74     	*(volatile unsigned long*)addr = b;
75     }
76     
77     /*
78      * I/O space operations
79      *
80      * Arrangement on a Sun is somewhat complicated.
81      *
82      * First of all, we want to use standard Linux drivers
83      * for keyboard, PC serial, etc. These drivers think
84      * they access I/O space and use inb/outb.
85      * On the other hand, EBus bridge accepts PCI *memory*
86      * cycles and converts them into ISA *I/O* cycles.
87      * Ergo, we want inb & outb to generate PCI memory cycles.
88      *
89      * If we want to issue PCI *I/O* cycles, we do this
90      * with a low 64K fixed window in PCIC. This window gets
91      * mapped somewhere into virtual kernel space and we
92      * can use inb/outb again.
93      */
94     #define inb_local(addr)		readb(addr)
95     #define inb(addr)		readb(addr)
96     #define inw(addr)		readw(addr)
97     #define inl(addr)		readl(addr)
98     #define inb_p(addr)		readb(addr)
99     
100     #define outb_local(b, addr)	writeb(b, addr)
101     #define outb(b, addr)		writeb(b, addr)
102     #define outw(b, addr)		writew(b, addr)
103     #define outl(b, addr)		writel(b, addr)
104     #define outb_p(b, addr)		writeb(b, addr)
105     
106     extern void outsb(unsigned long addr, const void *src, unsigned long cnt);
107     extern void outsw(unsigned long addr, const void *src, unsigned long cnt);
108     extern void outsl(unsigned long addr, const void *src, unsigned long cnt);
109     extern void insb(unsigned long addr, void *dst, unsigned long count);
110     extern void insw(unsigned long addr, void *dst, unsigned long count);
111     extern void insl(unsigned long addr, void *dst, unsigned long count);
112     
113     #define IO_SPACE_LIMIT 0xffffffff
114     
115     /*
116      * SBus accessors.
117      *
118      * SBus has only one, memory mapped, I/O space.
119      * We do not need to flip bytes for SBus of course.
120      */
121     extern __inline__ unsigned int _sbus_readb(unsigned long addr) {
122     	return *(volatile unsigned char*)addr;
123     }
124     
125     extern __inline__ unsigned int _sbus_readw(unsigned long addr) {
126     	return *(volatile unsigned short*)addr;
127     }
128     
129     extern __inline__ unsigned int _sbus_readl(unsigned long addr) {
130     	return *(volatile unsigned long*)addr;
131     }
132     
133     extern __inline__ void _sbus_writeb(unsigned char b, unsigned long addr) {
134     	*(volatile unsigned char*)addr = b;
135     }
136     
137     extern __inline__ void _sbus_writew(unsigned short b, unsigned long addr) {
138     	*(volatile unsigned short*)addr = b;
139     }
140     
141     extern __inline__ void _sbus_writel(unsigned int b, unsigned long addr) {
142     	*(volatile unsigned long*)addr = b;
143     }
144     
145     /*
146      * The only reason for #define's is to hide casts to unsigned long.
147      * XXX Rewrite drivers without structures for registers.
148      */
149     #define sbus_readb(a)	_sbus_readb((unsigned long)(a))
150     #define sbus_readw(a)	_sbus_readw((unsigned long)(a))
151     #define sbus_readl(a)	_sbus_readl((unsigned long)(a))
152     #define sbus_writeb(v, a)	_sbus_writeb(v, (unsigned long)(a))
153     #define sbus_writew(v, a)	_sbus_writew(v, (unsigned long)(a))
154     #define sbus_writel(v, a)	_sbus_writel(v, (unsigned long)(a))
155     
156     static inline void *sbus_memset_io(void *__dst, int c, __kernel_size_t n)
157     {
158     	unsigned long dst = (unsigned long)__dst;
159     
160     	while(n--) {
161     		sbus_writeb(c, dst);
162     		dst++;
163     	}
164     	return (void *) dst;
165     }
166     
167     #ifdef __KERNEL__
168     
169     /*
170      * Bus number may be embedded in the higher bits of the physical address.
171      * This is why we have no bus number argument to ioremap().
172      */
173     extern void *ioremap(unsigned long offset, unsigned long size);
174     #define ioremap_nocache(X,Y)	ioremap((X),(Y))
175     extern void iounmap(void *addr);
176     
177     /* P3: talk davem into dropping "name" argument in favor of res->name */
178     /*
179      * Bus number may be in res->flags... somewhere.
180      */
181     extern unsigned long sbus_ioremap(struct resource *res, unsigned long offset,
182         unsigned long size, char *name);
183     /* XXX Partial deallocations? I think not! */
184     extern void sbus_iounmap(unsigned long vaddr, unsigned long size);
185     
186     
187     #define virt_to_phys(x) __pa((unsigned long)(x))
188     #define phys_to_virt(x) __va((unsigned long)(x))
189     
190     /*
191      * At the moment, we do not use CMOS_READ anywhere outside of rtc.c,
192      * so rtc_port is static in it. This should not change unless a new
193      * hardware pops up.
194      */
195     #define RTC_PORT(x)   (rtc_port + (x))
196     #define RTC_ALWAYS_BCD  0
197     
198     /* Nothing to do */
199     /* P3: Only IDE DMA may need these. */
200     
201     #define dma_cache_inv(_start,_size)		do { } while (0)
202     #define dma_cache_wback(_start,_size)		do { } while (0)
203     #define dma_cache_wback_inv(_start,_size)	do { } while (0)
204     
205     #endif
206     
207     #endif /* !(__SPARC_IO_H) */
208