~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Linux/include/asm-ia64/io.h

Version: ~ [ 2.4.0 ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 #ifndef _ASM_IA64_IO_H
  2 #define _ASM_IA64_IO_H
  3 
  4 /*
  5  * This file contains the definitions for the emulated IO instructions
  6  * inb/inw/inl/outb/outw/outl and the "string versions" of the same
  7  * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
  8  * versions of the single-IO instructions (inb_p/inw_p/..).
  9  *
 10  * This file is not meant to be obfuscating: it's just complicated to
 11  * (a) handle it all in a way that makes gcc able to optimize it as
 12  * well as possible and (b) trying to avoid writing the same thing
 13  * over and over again with slight variations and possibly making a
 14  * mistake somewhere.
 15  *
 16  * Copyright (C) 1998-2000 Hewlett-Packard Co
 17  * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
 18  * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
 19  * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
 20  */
 21 
 22 /* We don't use IO slowdowns on the ia64, but.. */
 23 #define __SLOW_DOWN_IO  do { } while (0)
 24 #define SLOW_DOWN_IO    do { } while (0)
 25 
 26 #define __IA64_UNCACHED_OFFSET  0xc000000000000000      /* region 6 */
 27 
 28 #define IO_SPACE_LIMIT 0xffff
 29 
 30 # ifdef __KERNEL__
 31 
 32 #include <asm/machvec.h>
 33 #include <asm/page.h>
 34 #include <asm/system.h>
 35 
 36 /*
 37  * Change virtual addresses to physical addresses and vv.
 38  */
 39 static inline unsigned long
 40 virt_to_phys (volatile void *address)
 41 {
 42         return (unsigned long) address - PAGE_OFFSET;
 43 }
 44 
 45 static inline void*
 46 phys_to_virt(unsigned long address)
 47 {
 48         return (void *) (address + PAGE_OFFSET);
 49 }
 50 
 51 /*
 52  * The following two macros are deprecated and scheduled for removal.
 53  * Please use the PCI-DMA interface defined in <asm/pci.h> instead.
 54  */
 55 #define bus_to_virt     phys_to_virt
 56 #define virt_to_bus     virt_to_phys
 57 
 58 # endif /* KERNEL */
 59 
 60 /*
 61  * Memory fence w/accept.  This should never be used in code that is
 62  * not IA-64 specific.
 63  */
 64 #define __ia64_mf_a()   __asm__ __volatile__ ("mf.a" ::: "memory")
 65 
 66 static inline const unsigned long
 67 __ia64_get_io_port_base (void)
 68 {
 69         extern unsigned long ia64_iobase;
 70 
 71         return ia64_iobase;
 72 }
 73 
 74 static inline void*
 75 __ia64_mk_io_addr (unsigned long port)
 76 {
 77         const unsigned long io_base = __ia64_get_io_port_base();
 78         unsigned long addr;
 79 
 80         addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
 81         return (void *) addr;
 82 }
 83 
 84 /*
 85  * For the in/out instructions, we need to do:
 86  *
 87  *      o "mf" _before_ doing the I/O access to ensure that all prior
 88  *        accesses to memory occur before the I/O access
 89  *      o "mf.a" _after_ doing the I/O access to ensure that the access
 90  *        has completed before we're doing any other I/O accesses
 91  *
 92  * The former is necessary because we might be doing normal (cached) memory
 93  * accesses, e.g., to set up a DMA descriptor table and then do an "outX()"
 94  * to tell the DMA controller to start the DMA operation.  The "mf" ahead
 95  * of the I/O operation ensures that the DMA table is correct when the I/O
 96  * access occurs.
 97  *
 98  * The mf.a is necessary to ensure that all I/O access occur in program
 99  * order. --davidm 99/12/07 
100  */
101 
102 static inline unsigned int
103 __ia64_inb (unsigned long port)
104 {
105         volatile unsigned char *addr = __ia64_mk_io_addr(port);
106         unsigned char ret;
107 
108         ret = *addr;
109         __ia64_mf_a();
110         return ret;
111 }
112 
113 static inline unsigned int
114 __ia64_inw (unsigned long port)
115 {
116         volatile unsigned short *addr = __ia64_mk_io_addr(port);
117         unsigned short ret;
118 
119         ret = *addr;
120         __ia64_mf_a();
121         return ret;
122 }
123 
124 static inline unsigned int
125 __ia64_inl (unsigned long port)
126 {
127         volatile unsigned int *addr = __ia64_mk_io_addr(port);
128         unsigned int ret;
129 
130         ret = *addr;
131         __ia64_mf_a();
132         return ret;
133 }
134 
135 static inline void
136 __ia64_outb (unsigned char val, unsigned long port)
137 {
138         volatile unsigned char *addr = __ia64_mk_io_addr(port);
139 
140         *addr = val;
141         __ia64_mf_a();
142 }
143 
144 static inline void
145 __ia64_outw (unsigned short val, unsigned long port)
146 {
147         volatile unsigned short *addr = __ia64_mk_io_addr(port);
148 
149         *addr = val;
150         __ia64_mf_a();
151 }
152 
153 static inline void
154 __ia64_outl (unsigned int val, unsigned long port)
155 {
156         volatile unsigned int *addr = __ia64_mk_io_addr(port);
157 
158         *addr = val;
159         __ia64_mf_a();
160 }
161 
162 static inline void
163 __insb (unsigned long port, void *dst, unsigned long count)
164 {
165         unsigned char *dp = dst;
166 
167         if (platform_inb == __ia64_inb) {
168                 volatile unsigned char *addr = __ia64_mk_io_addr(port);
169 
170                 __ia64_mf_a();
171                 while (count--)
172                         *dp++ = *addr;
173                 __ia64_mf_a();
174         } else
175                 while (count--)
176                         *dp++ = platform_inb(port);
177         return;
178 }
179 
180 static inline void
181 __insw (unsigned long port, void *dst, unsigned long count)
182 {
183         unsigned short *dp = dst;
184 
185         if (platform_inw == __ia64_inw) {
186                 volatile unsigned short *addr = __ia64_mk_io_addr(port);
187 
188                 __ia64_mf_a();
189                 while (count--)
190                         *dp++ = *addr;
191                 __ia64_mf_a();
192         } else
193                 while (count--)
194                         *dp++ = platform_inw(port);
195         return;
196 }
197 
198 static inline void
199 __insl (unsigned long port, void *dst, unsigned long count)
200 {
201         unsigned int *dp = dst;
202 
203         if (platform_inl == __ia64_inl) {
204                 volatile unsigned int *addr = __ia64_mk_io_addr(port);
205 
206                 __ia64_mf_a();
207                 while (count--)
208                         *dp++ = *addr;
209                 __ia64_mf_a();
210         } else
211                 while (count--)
212                         *dp++ = platform_inl(port);
213         return;
214 }
215 
216 static inline void
217 __outsb (unsigned long port, const void *src, unsigned long count)
218 {
219         const unsigned char *sp = src;
220 
221         if (platform_outb == __ia64_outb) {
222                 volatile unsigned char *addr = __ia64_mk_io_addr(port);
223 
224                 while (count--)
225                         *addr = *sp++;
226                 __ia64_mf_a();
227         } else
228                 while (count--)
229                         platform_outb(*sp++, port);
230         return;
231 }
232 
233 static inline void
234 __outsw (unsigned long port, const void *src, unsigned long count)
235 {
236         const unsigned short *sp = src;
237 
238         if (platform_outw == __ia64_outw) {
239                 volatile unsigned short *addr = __ia64_mk_io_addr(port);
240 
241                 while (count--)
242                         *addr = *sp++;
243                 __ia64_mf_a();
244         } else
245                 while (count--)
246                         platform_outw(*sp++, port);
247         return;
248 }
249 
250 static inline void
251 __outsl (unsigned long port, void *src, unsigned long count)
252 {
253         const unsigned int *sp = src;
254 
255         if (platform_outl == __ia64_outl) {
256                 volatile unsigned int *addr = __ia64_mk_io_addr(port);
257 
258                 while (count--)
259                         *addr = *sp++;
260                 __ia64_mf_a();
261         } else
262                 while (count--)
263                         platform_outl(*sp++, port);
264         return;
265 }
266 
267 /*
268  * Unfortunately, some platforms are broken and do not follow the
269  * IA-64 architecture specification regarding legacy I/O support.
270  * Thus, we have to make these operations platform dependent...
271  */
272 #define __inb           platform_inb
273 #define __inw           platform_inw
274 #define __inl           platform_inl
275 #define __outb          platform_outb
276 #define __outw          platform_outw
277 #define __outl          platform_outl
278 
279 #define inb             __inb
280 #define inw             __inw
281 #define inl             __inl
282 #define insb            __insb
283 #define insw            __insw
284 #define insl            __insl
285 #define outb            __outb
286 #define outw            __outw
287 #define outl            __outl
288 #define outsb           __outsb
289 #define outsw           __outsw
290 #define outsl           __outsl
291 
292 /*
293  * The address passed to these functions are ioremap()ped already.
294  */
295 static inline unsigned char
296 __readb (void *addr)
297 {
298         return *(volatile unsigned char *)addr;
299 }
300 
301 static inline unsigned short
302 __readw (void *addr)
303 {
304         return *(volatile unsigned short *)addr;
305 }
306 
307 static inline unsigned int
308 __readl (void *addr)
309 {
310         return *(volatile unsigned int *) addr;
311 }
312 
313 static inline unsigned long
314 __readq (void *addr)
315 {
316         return *(volatile unsigned long *) addr;
317 }
318 
319 static inline void
320 __writeb (unsigned char val, void *addr)
321 {
322         *(volatile unsigned char *) addr = val;
323 }
324 
325 static inline void
326 __writew (unsigned short val, void *addr)
327 {
328         *(volatile unsigned short *) addr = val;
329 }
330 
331 static inline void
332 __writel (unsigned int val, void *addr)
333 {
334         *(volatile unsigned int *) addr = val;
335 }
336 
337 static inline void
338 __writeq (unsigned long val, void *addr)
339 {
340         *(volatile unsigned long *) addr = val;
341 }
342 
343 #define readb(a)        __readb((void *)(a))
344 #define readw(a)        __readw((void *)(a))
345 #define readl(a)        __readl((void *)(a))
346 #define readq(a)        __readqq((void *)(a))
347 #define __raw_readb     readb
348 #define __raw_readw     readw
349 #define __raw_readl     readl
350 #define __raw_readq     readq
351 #define writeb(v,a)     __writeb((v), (void *) (a))
352 #define writew(v,a)     __writew((v), (void *) (a))
353 #define writel(v,a)     __writel((v), (void *) (a))
354 #define writeq(v,a)     __writeq((v), (void *) (a))
355 #define __raw_writeb    writeb
356 #define __raw_writew    writew
357 #define __raw_writel    writel
358 #define __raw_writeq    writeq
359 
360 #ifndef inb_p
361 # define inb_p          inb
362 #endif
363 #ifndef inw_p
364 # define inw_p          inw
365 #endif
366 #ifndef inl_p
367 # define inl_p          inl
368 #endif
369 
370 #ifndef outb_p
371 # define outb_p         outb
372 #endif
373 #ifndef outw_p
374 # define outw_p         outw
375 #endif
376 #ifndef outl_p
377 # define outl_p         outl
378 #endif
379 
380 /*
381  * An "address" in IO memory space is not clearly either an integer
382  * or a pointer. We will accept both, thus the casts.
383  *
384  * On ia-64, we access the physical I/O memory space through the
385  * uncached kernel region.
386  */
387 static inline void *
388 ioremap (unsigned long offset, unsigned long size)
389 {
390         return (void *) (__IA64_UNCACHED_OFFSET | (offset));
391 } 
392 
393 static inline void
394 iounmap (void *addr)
395 {
396 }
397 
398 #define ioremap_nocache(o,s)    ioremap(o,s)
399 
400 # ifdef __KERNEL__
401 
402 /*
403  * String version of IO memory access ops:
404  */
405 extern void __ia64_memcpy_fromio (void *, unsigned long, long);
406 extern void __ia64_memcpy_toio (unsigned long, void *, long);
407 extern void __ia64_memset_c_io (unsigned long, unsigned long, long);
408 
409 #define memcpy_fromio(to,from,len) \
410   __ia64_memcpy_fromio((to),(unsigned long)(from),(len))
411 #define memcpy_toio(to,from,len) \
412   __ia64_memcpy_toio((unsigned long)(to),(from),(len))
413 #define memset_io(addr,c,len) \
414   __ia64_memset_c_io((unsigned long)(addr),0x0101010101010101UL*(u8)(c),(len))
415 
416 #define __HAVE_ARCH_MEMSETW_IO
417 #define memsetw_io(addr,c,len) \
418   _memset_c_io((unsigned long)(addr),0x0001000100010001UL*(u16)(c),(len))
419 
420 /*
421  * XXX - We don't have csum_partial_copy_fromio() yet, so we cheat here and 
422  * just copy it. The net code will then do the checksum later. Presently 
423  * only used by some shared memory 8390 Ethernet cards anyway.
424  */
425 
426 #define eth_io_copy_and_sum(skb,src,len,unused)         memcpy_fromio((skb)->data,(src),(len))
427 
428 #if 0
429 
430 /*
431  * XXX this is the kind of legacy stuff we want to get rid of with IA-64... --davidm 99/12/02
432  */
433 
434 /*
435  * This is used for checking BIOS signatures.  It's not clear at all
436  * why this is here.  This implementation seems to be the same on
437  * all architectures.  Strange.
438  */
439 static inline int
440 check_signature (unsigned long io_addr, const unsigned char *signature, int length)
441 {
442         int retval = 0;
443         do {
444                 if (readb(io_addr) != *signature)
445                         goto out;
446                 io_addr++;
447                 signature++;
448                 length--;
449         } while (length);
450         retval = 1;
451 out:
452         return retval;
453 }
454 
455 #define RTC_PORT(x)             (0x70 + (x))
456 #define RTC_ALWAYS_BCD          0
457 
458 #endif
459 
460 /*
461  * The caches on some architectures aren't DMA-coherent and have need
462  * to handle this in software.  There are two types of operations that
463  * can be applied to dma buffers.
464  *
465  * - dma_cache_inv(start, size) invalidates the affected parts of the
466  *   caches.  Dirty lines of the caches may be written back or simply
467  *   be discarded.  This operation is necessary before dma operations
468  *   to the memory.
469  *
470  * - dma_cache_wback(start, size) makes caches and memory coherent
471  *   by writing the content of the caches back to memory, if necessary
472  *   (cache flush).
473  *
474  * - dma_cache_wback_inv(start, size) Like dma_cache_wback() but the
475  *   function also invalidates the affected part of the caches as
476  *   necessary before DMA transfers from outside to memory.
477  *
478  * Fortunately, the IA-64 architecture mandates cache-coherent DMA, so
479  * these functions can be implemented as no-ops.
480  */
481 #define dma_cache_inv(_start,_size)             do { } while (0)
482 #define dma_cache_wback(_start,_size)           do { } while (0)
483 #define dma_cache_wback_inv(_start,_size)       do { } while (0)
484 
485 # endif /* __KERNEL__ */
486 #endif /* _ASM_IA64_IO_H */
487 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.