You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

io.h 4.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. #ifndef ETHERBOOT_IO_H
  2. #define ETHERBOOT_IO_H
  3. /* Don't require identity mapped physical memory,
  4. * osloader.c is the only valid user at the moment.
  5. */
  6. static inline unsigned long virt_to_phys(volatile const void *virt_addr)
  7. {
  8. return ((unsigned long)virt_addr);
  9. }
  10. static inline void *phys_to_virt(unsigned long phys_addr)
  11. {
  12. return (void *)(phys_addr);
  13. }
  14. /* virt_to_bus converts an addresss inside of etherboot [_start, _end]
  15. * into a memory address cards can use.
  16. */
  17. #define virt_to_bus virt_to_phys
  18. /* bus_to_virt reverses virt_to_bus, the address must be output
  19. * from virt_to_bus to be valid. This function does not work on
  20. * all bus addresses.
  21. */
  22. #define bus_to_virt phys_to_virt
  23. /* ioremap converts a random 32bit bus address into something
  24. * etherboot can access.
  25. */
  26. static inline void *ioremap(unsigned long bus_addr, unsigned long length __unused)
  27. {
  28. return bus_to_virt(bus_addr);
  29. }
  30. /* iounmap cleans up anything ioremap had to setup */
  31. static inline void iounmap(void *virt_addr __unused)
  32. {
  33. return;
  34. }
  35. /* In physical mode the offset of uncached pages */
  36. #define PHYS_BASE (0x8000000000000000UL)
  37. /* Memory mapped IO primitives, we avoid the cache... */
  38. static inline uint8_t readb(unsigned long addr)
  39. {
  40. return *((volatile uint8_t *)(PHYS_BASE | addr));
  41. }
  42. static inline uint16_t readw(unsigned long addr)
  43. {
  44. return *((volatile uint16_t *)(PHYS_BASE | addr));
  45. }
  46. static inline uint32_t readl(unsigned long addr)
  47. {
  48. return *((volatile uint32_t *)(PHYS_BASE | addr));
  49. }
  50. static inline uint64_t readq(unsigned long addr)
  51. {
  52. return *((volatile uint64_t *)(PHYS_BASE | addr));
  53. }
  54. static inline void writeb(uint8_t val, unsigned long addr)
  55. {
  56. *((volatile uint8_t *)(PHYS_BASE | addr)) = val;
  57. }
  58. static inline void writew(uint16_t val, unsigned long addr)
  59. {
  60. *((volatile uint16_t *)(PHYS_BASE | addr)) = val;
  61. }
  62. static inline void writel(uint32_t val, unsigned long addr)
  63. {
  64. *((volatile uint32_t *)(PHYS_BASE | addr)) = val;
  65. }
  66. static inline void writeq(uint64_t val, unsigned long addr)
  67. {
  68. *((volatile uint64_t *)(PHYS_BASE | addr)) = val;
  69. }
  70. static inline void memcpy_fromio(void *dest, unsigned long src, size_t n)
  71. {
  72. size_t i;
  73. uint8_t *dp = dest;
  74. for(i = 0; i < n; i++) {
  75. *dp = readb(src);
  76. dp++;
  77. src++;
  78. }
  79. }
  80. static inline void memcpy_toio(unsigned long dest , const void *src, size_t n)
  81. {
  82. size_t i;
  83. const uint8_t *sp = src;
  84. for(i = 0; i < n; i++) {
  85. writeb(*sp, dest);
  86. sp++;
  87. dest++;
  88. }
  89. }
  90. /* IO space IO primitives, Itanium has a strange architectural mapping... */
  91. extern unsigned long io_base;
  92. #define __ia64_mf_a() __asm__ __volatile__ ("mf.a" ::: "memory")
  93. #define __ia64_io_addr(port) ((void *)(PHYS_BASE | io_base | (((port) >> 2) << 12) | ((port) & 0xfff)))
  94. static inline uint8_t inb(unsigned long port)
  95. {
  96. uint8_t result;
  97. result = *((volatile uint8_t *)__ia64_io_addr(port));
  98. __ia64_mf_a();
  99. return result;
  100. }
  101. static inline uint16_t inw(unsigned long port)
  102. {
  103. uint8_t result;
  104. result = *((volatile uint16_t *)__ia64_io_addr(port));
  105. __ia64_mf_a();
  106. return result;
  107. }
  108. static inline uint32_t inl(unsigned long port)
  109. {
  110. uint32_t result;
  111. result = *((volatile uint32_t *)__ia64_io_addr(port));
  112. __ia64_mf_a();
  113. return result;
  114. }
  115. static inline void outb(uint8_t val, unsigned long port)
  116. {
  117. *((volatile uint8_t *)__ia64_io_addr(port)) = val;
  118. __ia64_mf_a();
  119. }
  120. static inline void outw(uint16_t val, unsigned long port)
  121. {
  122. *((volatile uint16_t *)__ia64_io_addr(port)) = val;
  123. __ia64_mf_a();
  124. }
  125. static inline void outl(uint32_t val, unsigned long port)
  126. {
  127. *((volatile uint32_t *)__ia64_io_addr(port)) = val;
  128. __ia64_mf_a();
  129. }
  130. static inline void insb(unsigned long port, void *dst, unsigned long count)
  131. {
  132. volatile uint8_t *addr = __ia64_io_addr(port);
  133. uint8_t *dp = dst;
  134. __ia64_mf_a();
  135. while(count--)
  136. *dp++ = *addr;
  137. __ia64_mf_a();
  138. }
  139. static inline void insw(unsigned long port, void *dst, unsigned long count)
  140. {
  141. volatile uint16_t *addr = __ia64_io_addr(port);
  142. uint16_t *dp = dst;
  143. __ia64_mf_a();
  144. while(count--)
  145. *dp++ = *addr;
  146. __ia64_mf_a();
  147. }
  148. static inline void insl(unsigned long port, void *dst, unsigned long count)
  149. {
  150. volatile uint32_t *addr = __ia64_io_addr(port);
  151. uint32_t *dp = dst;
  152. __ia64_mf_a();
  153. while(count--)
  154. *dp++ = *addr;
  155. __ia64_mf_a();
  156. }
  157. static inline void outsb(unsigned long port, void *src, unsigned long count)
  158. {
  159. const uint8_t *sp = src;
  160. volatile uint8_t *addr = __ia64_io_addr(port);
  161. while (count--)
  162. *addr = *sp++;
  163. __ia64_mf_a();
  164. }
  165. static inline void outsw(unsigned long port, void *src, unsigned long count)
  166. {
  167. const uint16_t *sp = src;
  168. volatile uint16_t *addr = __ia64_io_addr(port);
  169. while (count--)
  170. *addr = *sp++;
  171. __ia64_mf_a();
  172. }
  173. static inline void outsl(unsigned long port, void *src, unsigned long count)
  174. {
  175. const uint32_t *sp = src;
  176. volatile uint32_t *addr = __ia64_io_addr(port);
  177. while (count--)
  178. *addr = *sp++;
  179. __ia64_mf_a();
  180. }
  181. static inline unsigned long ia64_get_kr0(void)
  182. {
  183. unsigned long r;
  184. asm volatile ("mov %0=ar.k0" : "=r"(r));
  185. return r;
  186. }
  187. #endif /* ETHERBOOT_IO_H */