hwaccess.h 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337
  1. /*
  2. * This file is part of the flashrom project.
  3. *
  4. * Copyright (C) 2009 Carl-Daniel Hailfinger
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; version 2 of the License.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program; if not, write to the Free Software
  17. * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  18. */
  19. /*
  20. * Header file for hardware access and OS abstraction. Included from flash.h.
  21. */
  22. #ifndef __HWACCESS_H__
  23. #define __HWACCESS_H__ 1
  24. #if defined (__i386__) || defined (__x86_64__) || defined(__arm__)
  25. #include <sys/io.h>
  26. #endif
  27. #if NEED_PCI == 1
  28. /*
  29. * libpci headers use the variable name "index" which triggers shadowing
  30. * warnings on systems which have the index() function in a default #include
  31. * or as builtin.
  32. */
  33. #define index shadow_workaround_index
  34. #include <pci/pci.h>
  35. #undef index
  36. #endif
  37. #if defined (__i386__) || defined (__x86_64__)
  38. /* All x86 is little-endian. */
  39. #define __FLASHROM_LITTLE_ENDIAN__ 1
  40. #elif defined (__mips) || defined (__mips__) || defined (_mips) || defined (mips)
  41. /* MIPS can be either endian. */
  42. #if defined (__MIPSEL) || defined (__MIPSEL__) || defined (_MIPSEL) || defined (MIPSEL)
  43. #define __FLASHROM_LITTLE_ENDIAN__ 1
  44. #elif defined (__MIPSEB) || defined (__MIPSEB__) || defined (_MIPSEB) || defined (MIPSEB)
  45. #define __FLASHROM_BIG_ENDIAN__ 1
  46. #endif
  47. #elif defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || defined(__ppc64__)
  48. /* PowerPC can be either endian. */
  49. #if defined (_BIG_ENDIAN) || defined (__BIG_ENDIAN__)
  50. #define __FLASHROM_BIG_ENDIAN__ 1
  51. /* Error checking in case some weird header has #defines for LE as well. */
  52. #if defined (_LITTLE_ENDIAN) || defined (__LITTLE_ENDIAN__)
  53. #error Conflicting endianness #define
  54. #endif
  55. #else
  56. #error Little-endian PowerPC #defines are unknown
  57. #endif
  58. #endif
  59. #if !defined (__FLASHROM_BIG_ENDIAN__) && !defined (__FLASHROM_LITTLE_ENDIAN__)
  60. /* Nonstandard libc-specific macros for determining endianness. */
  61. #include <endian.h>
  62. #if BYTE_ORDER == LITTLE_ENDIAN
  63. #define __FLASHROM_LITTLE_ENDIAN__ 1
  64. #elif BYTE_ORDER == BIG_ENDIAN
  65. #define __FLASHROM_BIG_ENDIAN__ 1
  66. #endif
  67. #endif
  68. #if !defined (__FLASHROM_BIG_ENDIAN__) && !defined (__FLASHROM_LITTLE_ENDIAN__)
  69. #error Unable to determine endianness. Please add support for your arch or libc.
  70. #endif
  71. #define ___constant_swab8(x) ((uint8_t) ( \
  72. (((uint8_t)(x) & (uint8_t)0xffU))))
  73. #define ___constant_swab16(x) ((uint16_t) ( \
  74. (((uint16_t)(x) & (uint16_t)0x00ffU) << 8) | \
  75. (((uint16_t)(x) & (uint16_t)0xff00U) >> 8)))
  76. #define ___constant_swab32(x) ((uint32_t) ( \
  77. (((uint32_t)(x) & (uint32_t)0x000000ffUL) << 24) | \
  78. (((uint32_t)(x) & (uint32_t)0x0000ff00UL) << 8) | \
  79. (((uint32_t)(x) & (uint32_t)0x00ff0000UL) >> 8) | \
  80. (((uint32_t)(x) & (uint32_t)0xff000000UL) >> 24)))
  81. #define ___constant_swab64(x) ((uint64_t) ( \
  82. (((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \
  83. (((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
  84. (((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
  85. (((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
  86. (((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
  87. (((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
  88. (((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
  89. (((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56)))
  90. #if defined (__FLASHROM_BIG_ENDIAN__)
  91. #define cpu_to_le(bits) \
  92. static inline uint##bits##_t cpu_to_le##bits(uint##bits##_t val) \
  93. { \
  94. return ___constant_swab##bits(val); \
  95. }
  96. cpu_to_le(8)
  97. cpu_to_le(16)
  98. cpu_to_le(32)
  99. cpu_to_le(64)
  100. #define cpu_to_be8
  101. #define cpu_to_be16
  102. #define cpu_to_be32
  103. #define cpu_to_be64
  104. #elif defined (__FLASHROM_LITTLE_ENDIAN__)
  105. #define cpu_to_be(bits) \
  106. static inline uint##bits##_t cpu_to_be##bits(uint##bits##_t val) \
  107. { \
  108. return ___constant_swab##bits(val); \
  109. }
  110. cpu_to_be(8)
  111. cpu_to_be(16)
  112. cpu_to_be(32)
  113. cpu_to_be(64)
  114. #define cpu_to_le8
  115. #define cpu_to_le16
  116. #define cpu_to_le32
  117. #define cpu_to_le64
  118. #else
  119. #error Could not determine endianness.
  120. #endif
  121. #define be_to_cpu8 cpu_to_be8
  122. #define be_to_cpu16 cpu_to_be16
  123. #define be_to_cpu32 cpu_to_be32
  124. #define be_to_cpu64 cpu_to_be64
  125. #define le_to_cpu8 cpu_to_le8
  126. #define le_to_cpu16 cpu_to_le16
  127. #define le_to_cpu32 cpu_to_le32
  128. #define le_to_cpu64 cpu_to_le64
  129. #if NEED_PCI == 1
  130. #if defined (__i386__) || defined (__x86_64__)
  131. #define __FLASHROM_HAVE_OUTB__ 1
  132. /* for iopl and outb under Solaris */
  133. #if defined (__sun) && (defined(__i386) || defined(__amd64))
  134. #include <strings.h>
  135. #include <sys/sysi86.h>
  136. #include <sys/psw.h>
  137. #include <asm/sunddi.h>
  138. #endif
  139. #if (defined(__MACH__) && defined(__APPLE__))
  140. #define __DARWIN__
  141. #endif
  142. /* Clarification about OUTB/OUTW/OUTL argument order:
  143. * OUT[BWL](val, port)
  144. */
  145. #if defined(__FreeBSD__) || defined(__DragonFly__)
  146. #include <machine/cpufunc.h>
  147. #define off64_t off_t
  148. #define lseek64 lseek
  149. #define OUTB(x, y) do { u_int outb_tmp = (y); outb(outb_tmp, (x)); } while (0)
  150. #define OUTW(x, y) do { u_int outw_tmp = (y); outw(outw_tmp, (x)); } while (0)
  151. #define OUTL(x, y) do { u_int outl_tmp = (y); outl(outl_tmp, (x)); } while (0)
  152. #define INB(x) __extension__ ({ u_int inb_tmp = (x); inb(inb_tmp); })
  153. #define INW(x) __extension__ ({ u_int inw_tmp = (x); inw(inw_tmp); })
  154. #define INL(x) __extension__ ({ u_int inl_tmp = (x); inl(inl_tmp); })
  155. #else
  156. #if defined(__DARWIN__)
  157. /* Header is part of the DirectHW library. */
  158. #include <DirectHW/DirectHW.h>
  159. #define off64_t off_t
  160. #define lseek64 lseek
  161. #endif
  162. #if defined (__sun) && (defined(__i386) || defined(__amd64))
  163. /* Note different order for outb */
  164. #define OUTB(x,y) outb(y, x)
  165. #define OUTW(x,y) outw(y, x)
  166. #define OUTL(x,y) outl(y, x)
  167. #define INB inb
  168. #define INW inw
  169. #define INL inl
  170. #else
  171. #ifdef __DJGPP__
  172. #include <pc.h>
  173. #define OUTB(x,y) outportb(y, x)
  174. #define OUTW(x,y) outportw(y, x)
  175. #define OUTL(x,y) outportl(y, x)
  176. #define INB inportb
  177. #define INW inportw
  178. #define INL inportl
  179. #else
  180. #define OUTB outb
  181. #define OUTW outw
  182. #define OUTL outl
  183. #define INB inb
  184. #define INW inw
  185. #define INL inl
  186. #endif
  187. #endif
  188. #endif
  189. #if defined(__NetBSD__) || defined (__OpenBSD__)
  190. #define off64_t off_t
  191. #define lseek64 lseek
  192. #if defined(__i386__) || defined(__x86_64__)
  193. #include <sys/types.h>
  194. #include <machine/sysarch.h>
  195. #if defined(__NetBSD__)
  196. #if defined(__i386__)
  197. #define iopl i386_iopl
  198. #elif defined(__x86_64__)
  199. #define iopl x86_64_iopl
  200. #endif
  201. #elif defined (__OpenBSD__)
  202. #if defined(__i386__)
  203. #define iopl i386_iopl
  204. #elif defined(__amd64__)
  205. #define iopl amd64_iopl
  206. #endif
  207. #endif
  208. static inline void outb(uint8_t value, uint16_t port)
  209. {
  210. asm volatile ("outb %b0,%w1": :"a" (value), "Nd" (port));
  211. }
  212. static inline uint8_t inb(uint16_t port)
  213. {
  214. uint8_t value;
  215. asm volatile ("inb %w1,%0":"=a" (value):"Nd" (port));
  216. return value;
  217. }
  218. static inline void outw(uint16_t value, uint16_t port)
  219. {
  220. asm volatile ("outw %w0,%w1": :"a" (value), "Nd" (port));
  221. }
  222. static inline uint16_t inw(uint16_t port)
  223. {
  224. uint16_t value;
  225. asm volatile ("inw %w1,%0":"=a" (value):"Nd" (port));
  226. return value;
  227. }
  228. static inline void outl(uint32_t value, uint16_t port)
  229. {
  230. asm volatile ("outl %0,%w1": :"a" (value), "Nd" (port));
  231. }
  232. static inline uint32_t inl(uint16_t port)
  233. {
  234. uint32_t value;
  235. asm volatile ("inl %1,%0":"=a" (value):"Nd" (port));
  236. return value;
  237. }
  238. #endif
  239. #endif
  240. #if !defined(__DARWIN__) && !defined(__FreeBSD__) && !defined(__DragonFly__) && !defined(__LIBPAYLOAD__)
  241. typedef struct { uint32_t hi, lo; } msr_t;
  242. msr_t rdmsr(int addr);
  243. int wrmsr(int addr, msr_t msr);
  244. #endif
  245. #if defined(__FreeBSD__) || defined(__DragonFly__)
  246. /* FreeBSD already has conflicting definitions for wrmsr/rdmsr. */
  247. #undef rdmsr
  248. #undef wrmsr
  249. #define rdmsr freebsd_rdmsr
  250. #define wrmsr freebsd_wrmsr
  251. typedef struct { uint32_t hi, lo; } msr_t;
  252. msr_t freebsd_rdmsr(int addr);
  253. int freebsd_wrmsr(int addr, msr_t msr);
  254. #endif
  255. #if defined(__LIBPAYLOAD__)
  256. #include <arch/io.h>
  257. #include <arch/msr.h>
  258. typedef struct { uint32_t hi, lo; } msr_t;
  259. msr_t libpayload_rdmsr(int addr);
  260. int libpayload_wrmsr(int addr, msr_t msr);
  261. #undef rdmsr
  262. #define rdmsr libpayload_rdmsr
  263. #define wrmsr libpayload_wrmsr
  264. #endif
  265. #elif defined(__powerpc__) || defined(__powerpc64__) || defined(__ppc__) || defined(__ppc64__)
  266. /* PCI port I/O is not yet implemented on PowerPC. */
  267. #elif defined (__mips) || defined (__mips__) || defined (_mips) || defined (mips)
  268. /* PCI port I/O is not yet implemented on MIPS. */
  269. #elif defined(__arm__)
  270. /* Non memory mapped I/O is not supported on ARM. */
  271. #else
  272. #error Unknown architecture, please check if it supports PCI port IO.
  273. #endif
  274. #endif
  275. #endif /* !__HWACCESS_H__ */