io.h
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:8k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. #ifndef _ASM_IO_H
  2. #define _ASM_IO_H
  3. #include <linux/config.h>
  4. /*
  5.  * This file contains the definitions for the x86 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
  11.  * to (a) handle it all in a way that makes gcc able to optimize it
  12.  * as 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. /*
  17.  * Thanks to James van Artsdalen for a better timing-fix than
  18.  * the two short jumps: using outb's to a nonexistent port seems
  19.  * to guarantee better timings even on fast machines.
  20.  *
  21.  * On the other hand, I'd like to be sure of a non-existent port:
  22.  * I feel a bit unsafe about using 0x80 (should be safe, though)
  23.  *
  24.  * Linus
  25.  */
  26.  /*
  27.   *  Bit simplified and optimized by Jan Hubicka
  28.   *  Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999.
  29.   *
  30.   *  isa_memset_io, isa_memcpy_fromio, isa_memcpy_toio added,
  31.   *  isa_read[wl] and isa_write[wl] fixed
  32.   *  - Arnaldo Carvalho de Melo <acme@conectiva.com.br>
  33.   */
  34. #ifdef SLOW_IO_BY_JUMPING
  35. #define __SLOW_DOWN_IO "njmp 1fn1:tjmp 1fn1:"
  36. #else
  37. #define __SLOW_DOWN_IO "noutb %%al,$0x80"
  38. #endif
  39. #ifdef REALLY_SLOW_IO
  40. #define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO __SLOW_DOWN_IO
  41. #else
  42. #define __FULL_SLOW_DOWN_IO __SLOW_DOWN_IO
  43. #endif
  44. /*
  45.  * Talk about misusing macros..
  46.  */
  47. #define __OUT1(s,x) 
  48. extern inline void out##s(unsigned x value, unsigned short port) {
  49. #define __OUT2(s,s1,s2) 
  50. __asm__ __volatile__ ("out" #s " %" s1 "0,%" s2 "1"
  51. #define __OUT(s,s1,x) 
  52. __OUT1(s,x) __OUT2(s,s1,"w") : : "a" (value), "Nd" (port)); } 
  53. __OUT1(s##_p,x) __OUT2(s,s1,"w") __FULL_SLOW_DOWN_IO : : "a" (value), "Nd" (port));} 
  54. #define __IN1(s) 
  55. extern inline RETURN_TYPE in##s(unsigned short port) { RETURN_TYPE _v;
  56. #define __IN2(s,s1,s2) 
  57. __asm__ __volatile__ ("in" #s " %" s2 "1,%" s1 "0"
  58. #define __IN(s,s1,i...) 
  59. __IN1(s) __IN2(s,s1,"w") : "=a" (_v) : "Nd" (port) ,##i ); return _v; } 
  60. __IN1(s##_p) __IN2(s,s1,"w") __FULL_SLOW_DOWN_IO : "=a" (_v) : "Nd" (port) ,##i ); return _v; } 
  61. #define __INS(s) 
  62. extern inline void ins##s(unsigned short port, void * addr, unsigned long count) 
  63. { __asm__ __volatile__ ("rep ; ins" #s 
  64. : "=D" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
  65. #define __OUTS(s) 
  66. extern inline void outs##s(unsigned short port, const void * addr, unsigned long count) 
  67. { __asm__ __volatile__ ("rep ; outs" #s 
  68. : "=S" (addr), "=c" (count) : "d" (port),"0" (addr),"1" (count)); }
  69. #define RETURN_TYPE unsigned char
  70. __IN(b,"")
  71. #undef RETURN_TYPE
  72. #define RETURN_TYPE unsigned short
  73. __IN(w,"")
  74. #undef RETURN_TYPE
  75. #define RETURN_TYPE unsigned int
  76. __IN(l,"")
  77. #undef RETURN_TYPE
  78. __OUT(b,"b",char)
  79. __OUT(w,"w",short)
  80. __OUT(l,,int)
  81. __INS(b)
  82. __INS(w)
  83. __INS(l)
  84. __OUTS(b)
  85. __OUTS(w)
  86. __OUTS(l)
  87. #define IO_SPACE_LIMIT 0xffff
  88. #ifdef __KERNEL__
  89. #include <linux/vmalloc.h>
  90. /*
  91.  * Temporary debugging check to catch old code using
  92.  * unmapped ISA addresses. Will be removed in 2.4.
  93.  */
  94. #ifdef CONFIG_IO_DEBUG
  95.   extern void *__io_virt_debug(unsigned long x, const char *file, int line);
  96.   extern unsigned long __io_phys_debug(unsigned long x, const char *file, int line);
  97.   #define __io_virt(x) __io_virt_debug((unsigned long)(x), __FILE__, __LINE__)
  98. //#define __io_phys(x) __io_phys_debug((unsigned long)(x), __FILE__, __LINE__)
  99. #else
  100.   #define __io_virt(x) ((void *)(x))
  101. //#define __io_phys(x) __pa(x)
  102. #endif
  103. /*
  104.  * Change virtual addresses to physical addresses and vv.
  105.  * These are pretty trivial
  106.  */
  107. extern inline unsigned long virt_to_phys(volatile void * address)
  108. {
  109. return __pa(address);
  110. }
  111. extern inline void * phys_to_virt(unsigned long address)
  112. {
  113. return __va(address);
  114. }
  115. /*
  116.  * Change "struct page" to physical address.
  117.  */
  118. #ifdef CONFIG_DISCONTIGMEM
  119. #include <asm/mmzone.h>
  120. #else
  121. #define page_to_phys(page) (((page) - mem_map) << PAGE_SHIFT)
  122. #endif
  123. extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags);
  124. extern inline void * ioremap (unsigned long offset, unsigned long size)
  125. {
  126. return __ioremap(offset, size, 0);
  127. }
  128. /*
  129.  * This one maps high address device memory and turns off caching for that area.
  130.  * it's useful if some control registers are in such an area and write combining
  131.  * or read caching is not desirable:
  132.  */
  133. extern inline void * ioremap_nocache (unsigned long offset, unsigned long size)
  134. {
  135.         return __ioremap(offset, size, _PAGE_PCD);
  136. }
  137. extern void iounmap(void *addr);
  138. /*
  139.  * IO bus memory addresses are also 1:1 with the physical address
  140.  */
  141. #define virt_to_bus virt_to_phys
  142. #define bus_to_virt phys_to_virt
  143. #define page_to_bus page_to_phys
  144. /*
  145.  * readX/writeX() are used to access memory mapped devices. On some
  146.  * architectures the memory mapped IO stuff needs to be accessed
  147.  * differently. On the x86 architecture, we just read/write the
  148.  * memory location directly.
  149.  */
  150. #define readb(addr) (*(volatile unsigned char *) __io_virt(addr))
  151. #define readw(addr) (*(volatile unsigned short *) __io_virt(addr))
  152. #define readl(addr) (*(volatile unsigned int *) __io_virt(addr))
  153. #define __raw_readb readb
  154. #define __raw_readw readw
  155. #define __raw_readl readl
  156. #define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b))
  157. #define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b))
  158. #define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b))
  159. #define __raw_writeb writeb
  160. #define __raw_writew writew
  161. #define __raw_writel writel
  162. void *memcpy_fromio(void*,const void*,unsigned); 
  163. void *memcpy_toio(void*,const void*,unsigned); 
  164. #define memset_io(a,b,c) memset(__io_virt(a),(b),(c))
  165. /*
  166.  * ISA space is 'always mapped' on a typical x86 system, no need to
  167.  * explicitly ioremap() it. The fact that the ISA IO space is mapped
  168.  * to PAGE_OFFSET is pure coincidence - it does not mean ISA values
  169.  * are physical addresses. The following constant pointer can be
  170.  * used as the IO-area pointer (it can be iounmapped as well, so the
  171.  * analogy with PCI is quite large):
  172.  */
  173. #define __ISA_IO_base ((char *)(PAGE_OFFSET))
  174. #define isa_readb(a) readb(__ISA_IO_base + (a))
  175. #define isa_readw(a) readw(__ISA_IO_base + (a))
  176. #define isa_readl(a) readl(__ISA_IO_base + (a))
  177. #define isa_writeb(b,a) writeb(b,__ISA_IO_base + (a))
  178. #define isa_writew(w,a) writew(w,__ISA_IO_base + (a))
  179. #define isa_writel(l,a) writel(l,__ISA_IO_base + (a))
  180. #define isa_memset_io(a,b,c) memset_io(__ISA_IO_base + (a),(b),(c))
  181. #define isa_memcpy_fromio(a,b,c) memcpy_fromio((a),__ISA_IO_base + (b),(c))
  182. #define isa_memcpy_toio(a,b,c) memcpy_toio(__ISA_IO_base + (a),(b),(c))
  183. /*
  184.  * Again, x86-64 does not require mem IO specific function.
  185.  */
  186. #define eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__io_virt(b),(c),(d))
  187. #define isa_eth_io_copy_and_sum(a,b,c,d) eth_copy_and_sum((a),__io_virt(__ISA_IO_base + (b)),(c),(d))
  188. static inline int check_signature(unsigned long io_addr,
  189. const unsigned char *signature, int length)
  190. {
  191. int retval = 0;
  192. do {
  193. if (readb(io_addr) != *signature)
  194. goto out;
  195. io_addr++;
  196. signature++;
  197. length--;
  198. } while (length);
  199. retval = 1;
  200. out:
  201. return retval;
  202. }
  203. static inline int isa_check_signature(unsigned long io_addr,
  204. const unsigned char *signature, int length)
  205. {
  206. int retval = 0;
  207. do {
  208. if (isa_readb(io_addr) != *signature)
  209. goto out;
  210. io_addr++;
  211. signature++;
  212. length--;
  213. } while (length);
  214. retval = 1;
  215. out:
  216. return retval;
  217. }
  218. /* Nothing to do */
  219. #define dma_cache_inv(_start,_size) do { } while (0)
  220. #define dma_cache_wback(_start,_size) do { } while (0)
  221. #define dma_cache_wback_inv(_start,_size) do { } while (0)
  222. #define flush_write_buffers() 
  223. #endif /* __KERNEL__ */
  224. #endif