io.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:9k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. #ifndef _ASM_IA64_IO_H
  2. #define _ASM_IA64_IO_H
  3. /*
  4.  * This file contains the definitions for the emulated IO instructions
  5.  * inb/inw/inl/outb/outw/outl and the "string versions" of the same
  6.  * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
  7.  * versions of the single-IO instructions (inb_p/inw_p/..).
  8.  *
  9.  * This file is not meant to be obfuscating: it's just complicated to
  10.  * (a) handle it all in a way that makes gcc able to optimize it as
  11.  * well as possible and (b) trying to avoid writing the same thing
  12.  * over and over again with slight variations and possibly making a
  13.  * mistake somewhere.
  14.  *
  15.  * Copyright (C) 1998-2001 Hewlett-Packard Co
  16.  * David Mosberger-Tang <davidm@hpl.hp.com>
  17.  * Copyright (C) 1999 Asit Mallick <asit.k.mallick@intel.com>
  18.  * Copyright (C) 1999 Don Dugger <don.dugger@intel.com>
  19.  */
  20. /* We don't use IO slowdowns on the ia64, but.. */
  21. #define __SLOW_DOWN_IO do { } while (0)
  22. #define SLOW_DOWN_IO do { } while (0)
  23. #define __IA64_UNCACHED_OFFSET 0xc000000000000000 /* region 6 */
  24. /*
  25.  * The legacy I/O space defined by the ia64 architecture supports only 65536 ports, but
  26.  * large machines may have multiple other I/O spaces so we can't place any a priori limit
  27.  * on IO_SPACE_LIMIT.  These additional spaces are described in ACPI.
  28.  */
  29. #define IO_SPACE_LIMIT 0xffffffffffffffffUL
  30. # ifdef __KERNEL__
  31. #include <asm/machvec.h>
  32. #include <asm/page.h>
  33. #include <asm/system.h>
  34. /*
  35.  * Change virtual addresses to physical addresses and vv.
  36.  */
  37. static inline unsigned long
  38. virt_to_phys (volatile void *address)
  39. {
  40. return (unsigned long) address - PAGE_OFFSET;
  41. }
  42. static inline void*
  43. phys_to_virt (unsigned long address)
  44. {
  45. return (void *) (address + PAGE_OFFSET);
  46. }
  47. /*
  48.  * The following two macros are deprecated and scheduled for removal.
  49.  * Please use the PCI-DMA interface defined in <asm/pci.h> instead.
  50.  */
  51. #define bus_to_virt phys_to_virt
  52. #define virt_to_bus virt_to_phys
  53. #define page_to_bus page_to_phys
  54. # endif /* KERNEL */
  55. /*
  56.  * Memory fence w/accept.  This should never be used in code that is
  57.  * not IA-64 specific.
  58.  */
  59. #define __ia64_mf_a() __asm__ __volatile__ ("mf.a" ::: "memory")
  60. static inline const unsigned long
  61. __ia64_get_io_port_base (void)
  62. {
  63. extern unsigned long ia64_iobase;
  64. return ia64_iobase;
  65. }
  66. static inline void*
  67. __ia64_mk_io_addr (unsigned long port)
  68. {
  69. const unsigned long io_base = __ia64_get_io_port_base();
  70. unsigned long addr;
  71. addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
  72. return (void *) addr;
  73. }
  74. /*
  75.  * For the in/out routines, we need to do "mf.a" _after_ doing the I/O access to ensure
  76.  * that the access has completed before executing other I/O accesses.  Since we're doing
  77.  * the accesses through an uncachable (UC) translation, the CPU will execute them in
  78.  * program order.  However, we still need to tell the compiler not to shuffle them around
  79.  * during optimization, which is why we use "volatile" pointers.
  80.  */
  81. static inline unsigned int
  82. __ia64_inb (unsigned long port)
  83. {
  84. volatile unsigned char *addr = __ia64_mk_io_addr(port);
  85. unsigned char ret;
  86. ret = *addr;
  87. __ia64_mf_a();
  88. return ret;
  89. }
  90. static inline unsigned int
  91. __ia64_inw (unsigned long port)
  92. {
  93. volatile unsigned short *addr = __ia64_mk_io_addr(port);
  94. unsigned short ret;
  95. ret = *addr;
  96. __ia64_mf_a();
  97. return ret;
  98. }
  99. static inline unsigned int
  100. __ia64_inl (unsigned long port)
  101. {
  102. volatile unsigned int *addr = __ia64_mk_io_addr(port);
  103. unsigned int ret;
  104. ret = *addr;
  105. __ia64_mf_a();
  106. return ret;
  107. }
  108. static inline void
  109. __ia64_outb (unsigned char val, unsigned long port)
  110. {
  111. volatile unsigned char *addr = __ia64_mk_io_addr(port);
  112. *addr = val;
  113. __ia64_mf_a();
  114. }
  115. static inline void
  116. __ia64_outw (unsigned short val, unsigned long port)
  117. {
  118. volatile unsigned short *addr = __ia64_mk_io_addr(port);
  119. *addr = val;
  120. __ia64_mf_a();
  121. }
  122. static inline void
  123. __ia64_outl (unsigned int val, unsigned long port)
  124. {
  125. volatile unsigned int *addr = __ia64_mk_io_addr(port);
  126. *addr = val;
  127. __ia64_mf_a();
  128. }
  129. static inline void
  130. __insb (unsigned long port, void *dst, unsigned long count)
  131. {
  132. unsigned char *dp = dst;
  133. if (platform_inb == __ia64_inb) {
  134. volatile unsigned char *addr = __ia64_mk_io_addr(port);
  135. __ia64_mf_a();
  136. while (count--)
  137. *dp++ = *addr;
  138. __ia64_mf_a();
  139. } else
  140. while (count--)
  141. *dp++ = platform_inb(port);
  142. return;
  143. }
  144. static inline void
  145. __insw (unsigned long port, void *dst, unsigned long count)
  146. {
  147. unsigned short *dp = dst;
  148. if (platform_inw == __ia64_inw) {
  149. volatile unsigned short *addr = __ia64_mk_io_addr(port);
  150. __ia64_mf_a();
  151. while (count--)
  152. *dp++ = *addr;
  153. __ia64_mf_a();
  154. } else
  155. while (count--)
  156. *dp++ = platform_inw(port);
  157. return;
  158. }
  159. static inline void
  160. __insl (unsigned long port, void *dst, unsigned long count)
  161. {
  162. unsigned int *dp = dst;
  163. if (platform_inl == __ia64_inl) {
  164. volatile unsigned int *addr = __ia64_mk_io_addr(port);
  165. __ia64_mf_a();
  166. while (count--)
  167. *dp++ = *addr;
  168. __ia64_mf_a();
  169. } else
  170. while (count--)
  171. *dp++ = platform_inl(port);
  172. return;
  173. }
  174. static inline void
  175. __outsb (unsigned long port, const void *src, unsigned long count)
  176. {
  177. const unsigned char *sp = src;
  178. if (platform_outb == __ia64_outb) {
  179. volatile unsigned char *addr = __ia64_mk_io_addr(port);
  180. while (count--)
  181. *addr = *sp++;
  182. __ia64_mf_a();
  183. } else
  184. while (count--)
  185. platform_outb(*sp++, port);
  186. return;
  187. }
  188. static inline void
  189. __outsw (unsigned long port, const void *src, unsigned long count)
  190. {
  191. const unsigned short *sp = src;
  192. if (platform_outw == __ia64_outw) {
  193. volatile unsigned short *addr = __ia64_mk_io_addr(port);
  194. while (count--)
  195. *addr = *sp++;
  196. __ia64_mf_a();
  197. } else
  198. while (count--)
  199. platform_outw(*sp++, port);
  200. return;
  201. }
  202. static inline void
  203. __outsl (unsigned long port, void *src, unsigned long count)
  204. {
  205. const unsigned int *sp = src;
  206. if (platform_outl == __ia64_outl) {
  207. volatile unsigned int *addr = __ia64_mk_io_addr(port);
  208. while (count--)
  209. *addr = *sp++;
  210. __ia64_mf_a();
  211. } else
  212. while (count--)
  213. platform_outl(*sp++, port);
  214. return;
  215. }
  216. /*
  217.  * Unfortunately, some platforms are broken and do not follow the
  218.  * IA-64 architecture specification regarding legacy I/O support.
  219.  * Thus, we have to make these operations platform dependent...
  220.  */
  221. #define __inb platform_inb
  222. #define __inw platform_inw
  223. #define __inl platform_inl
  224. #define __outb platform_outb
  225. #define __outw platform_outw
  226. #define __outl platform_outl
  227. #define inb __inb
  228. #define inw __inw
  229. #define inl __inl
  230. #define insb __insb
  231. #define insw __insw
  232. #define insl __insl
  233. #define outb __outb
  234. #define outw __outw
  235. #define outl __outl
  236. #define outsb __outsb
  237. #define outsw __outsw
  238. #define outsl __outsl
  239. /*
  240.  * The address passed to these functions are ioremap()ped already.
  241.  */
  242. static inline unsigned char
  243. __readb (void *addr)
  244. {
  245. return *(volatile unsigned char *)addr;
  246. }
  247. static inline unsigned short
  248. __readw (void *addr)
  249. {
  250. return *(volatile unsigned short *)addr;
  251. }
  252. static inline unsigned int
  253. __readl (void *addr)
  254. {
  255. return *(volatile unsigned int *) addr;
  256. }
  257. static inline unsigned long
  258. __readq (void *addr)
  259. {
  260. return *(volatile unsigned long *) addr;
  261. }
  262. static inline void
  263. __writeb (unsigned char val, void *addr)
  264. {
  265. *(volatile unsigned char *) addr = val;
  266. }
  267. static inline void
  268. __writew (unsigned short val, void *addr)
  269. {
  270. *(volatile unsigned short *) addr = val;
  271. }
  272. static inline void
  273. __writel (unsigned int val, void *addr)
  274. {
  275. *(volatile unsigned int *) addr = val;
  276. }
  277. static inline void
  278. __writeq (unsigned long val, void *addr)
  279. {
  280. *(volatile unsigned long *) addr = val;
  281. }
  282. #define readb(a) __readb((void *)(a))
  283. #define readw(a) __readw((void *)(a))
  284. #define readl(a) __readl((void *)(a))
  285. #define readq(a) __readq((void *)(a))
  286. #define __raw_readb readb
  287. #define __raw_readw readw
  288. #define __raw_readl readl
  289. #define __raw_readq readq
  290. #define writeb(v,a) __writeb((v), (void *) (a))
  291. #define writew(v,a) __writew((v), (void *) (a))
  292. #define writel(v,a) __writel((v), (void *) (a))
  293. #define writeq(v,a) __writeq((v), (void *) (a))
  294. #define __raw_writeb writeb
  295. #define __raw_writew writew
  296. #define __raw_writel writel
  297. #define __raw_writeq writeq
  298. #ifndef inb_p
  299. # define inb_p inb
  300. #endif
  301. #ifndef inw_p
  302. # define inw_p inw
  303. #endif
  304. #ifndef inl_p
  305. # define inl_p inl
  306. #endif
  307. #ifndef outb_p
  308. # define outb_p outb
  309. #endif
  310. #ifndef outw_p
  311. # define outw_p outw
  312. #endif
  313. #ifndef outl_p
  314. # define outl_p outl
  315. #endif
  316. /*
  317.  * An "address" in IO memory space is not clearly either an integer or a pointer. We will
  318.  * accept both, thus the casts.
  319.  *
  320.  * On ia-64, we access the physical I/O memory space through the uncached kernel region.
  321.  */
  322. static inline void *
  323. ioremap (unsigned long offset, unsigned long size)
  324. {
  325. return (void *) (__IA64_UNCACHED_OFFSET | (offset));
  326. }
  327. static inline void
  328. iounmap (void *addr)
  329. {
  330. }
  331. #define ioremap_nocache(o,s) ioremap(o,s)
  332. # ifdef __KERNEL__
  333. /*
  334.  * String version of IO memory access ops:
  335.  */
  336. extern void __ia64_memcpy_fromio (void *, unsigned long, long);
  337. extern void __ia64_memcpy_toio (unsigned long, void *, long);
  338. extern void __ia64_memset_c_io (unsigned long, unsigned long, long);
  339. #define memcpy_fromio(to,from,len) 
  340.   __ia64_memcpy_fromio((to),(unsigned long)(from),(len))
  341. #define memcpy_toio(to,from,len) 
  342.   __ia64_memcpy_toio((unsigned long)(to),(from),(len))
  343. #define memset_io(addr,c,len) 
  344.   __ia64_memset_c_io((unsigned long)(addr),0x0101010101010101UL*(u8)(c),(len))
  345. # endif /* __KERNEL__ */
  346. #endif /* _ASM_IA64_IO_H */