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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* $Id: io.c,v 1.4 1999/08/18 23:37:46 ralf Exp $
  2.  *
  3.  * This file is subject to the terms and conditions of the GNU General Public
  4.  * License.  See the file "COPYING" in the main directory of this archive
  5.  * for more details.
  6.  *
  7.  * Low level I/O functions for SNI.
  8.  */
  9. #include <linux/string.h>
  10. #include <linux/spinlock.h>
  11. #include <asm/addrspace.h>
  12. #include <asm/system.h>
  13. #include <asm/sni.h>
  14. /*
  15.  * Urgs...  We only can see a 16mb window of the 4gb EISA address space
  16.  * at PCIMT_EISA_BASE.  Maladia segmentitis ...
  17.  *
  18.  * To avoid locking and all the related headacke we implement this such
  19.  * that accessing the bus address space nests, so we're treating this
  20.  * correctly even for interrupts.  This is going to suck seriously for
  21.  * the SMP members of the RM family.
  22.  *
  23.  * Making things worse the PCIMT_CSMAPISA register resides on the X bus with
  24.  * it's unbeatable 1.4 mb/s transfer rate.
  25.  */
  26. static inline void eisa_map(unsigned long address)
  27. {
  28. unsigned char upper;
  29. upper = address >> 24;
  30. *(volatile unsigned char *)PCIMT_CSMAPISA = ~upper;
  31. }
  32. #define save_eisa_map()
  33. (*(volatile unsigned char *)PCIMT_CSMAPISA)
  34. #define restore_eisa_map(val)
  35. do { (*(volatile unsigned char *)PCIMT_CSMAPISA) = val; } while(0)
  36. static unsigned char sni_readb(unsigned long addr)
  37. {
  38. unsigned char res;
  39. unsigned int save_map;
  40. save_map = save_eisa_map();
  41. eisa_map(addr);
  42. addr &= 0xffffff;
  43. res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr);
  44. restore_eisa_map(save_map);
  45. return res;
  46. }
  47. static unsigned short sni_readw(unsigned long addr)
  48. {
  49. unsigned short res;
  50. unsigned int save_map;
  51. save_map = save_eisa_map();
  52. eisa_map(addr);
  53. addr &= 0xffffff;
  54. res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr);
  55. restore_eisa_map(save_map);
  56. return res;
  57. }
  58. static unsigned int sni_readl(unsigned long addr)
  59. {
  60. unsigned int res;
  61. unsigned int save_map;
  62. save_map = save_eisa_map();
  63. eisa_map(addr);
  64. addr &= 0xffffff;
  65. res = *(volatile unsigned char *) (PCIMT_EISA_BASE + addr);
  66. restore_eisa_map(save_map);
  67. return res;
  68. }
  69. static void sni_writeb(unsigned char val, unsigned long addr)
  70. {
  71. unsigned int save_map;
  72. save_map = save_eisa_map();
  73. eisa_map(addr);
  74. addr &= 0xffffff;
  75. *(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val;
  76. restore_eisa_map(save_map);
  77. }
  78. static void sni_writew(unsigned short val, unsigned long addr)
  79. {
  80. unsigned int save_map;
  81. save_map = save_eisa_map();
  82. eisa_map(addr);
  83. addr &= 0xffffff;
  84. *(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val;
  85. restore_eisa_map(save_map);
  86. }
  87. static void sni_writel(unsigned int val, unsigned long addr)
  88. {
  89. unsigned int save_map;
  90. save_map = save_eisa_map();
  91. eisa_map(addr);
  92. addr &= 0xffffff;
  93. *(volatile unsigned char *) (PCIMT_EISA_BASE + addr) = val;
  94. restore_eisa_map(save_map);
  95. }
  96. static void sni_memset_io(unsigned long addr, int val, unsigned long len)
  97. {
  98. unsigned long waddr;
  99. unsigned int save_map;
  100. save_map = save_eisa_map();
  101. waddr = PCIMT_EISA_BASE | (addr & 0xffffff);
  102. while(len) {
  103. unsigned long fraglen;
  104. fraglen = (~addr + 1) & 0xffffff;
  105. fraglen = (fraglen < len) ? fraglen : len;
  106. eisa_map(addr);
  107. memset((char *)waddr, val, fraglen);
  108. addr += fraglen;
  109. waddr = waddr + fraglen - 0x1000000;
  110. len -= fraglen;
  111. }
  112. restore_eisa_map(save_map);
  113. }
  114. static void sni_memcpy_fromio(unsigned long to, unsigned long from, unsigned long len)
  115. {
  116. unsigned long waddr;
  117. unsigned int save_map;
  118. save_map = save_eisa_map();
  119. waddr = PCIMT_EISA_BASE | (from & 0xffffff);
  120. while(len) {
  121. unsigned long fraglen;
  122. fraglen = (~from + 1) & 0xffffff;
  123. fraglen = (fraglen < len) ? fraglen : len;
  124. eisa_map(from);
  125. memcpy((void *)to, (void *)waddr, fraglen);
  126. to += fraglen;
  127. from += fraglen;
  128. waddr = waddr + fraglen - 0x1000000;
  129. len -= fraglen;
  130. }
  131. restore_eisa_map(save_map);
  132. }
  133. static void sni_memcpy_toio(unsigned long to, unsigned long from, unsigned long len)
  134. {
  135. unsigned long waddr;
  136. unsigned int save_map;
  137. save_map = save_eisa_map();
  138. waddr = PCIMT_EISA_BASE | (to & 0xffffff);
  139. while(len) {
  140. unsigned long fraglen;
  141. fraglen = (~to + 1) & 0xffffff;
  142. fraglen = (fraglen < len) ? fraglen : len;
  143. eisa_map(to);
  144. memcpy((char *)to + PCIMT_EISA_BASE, (void *)from, fraglen);
  145. to += fraglen;
  146. from += fraglen;
  147. waddr = waddr + fraglen - 0x1000000;
  148. len -= fraglen;
  149. }
  150. restore_eisa_map(save_map);
  151. }