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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531
  1. #ifndef _IPXE_IO_H
  2. #define _IPXE_IO_H
  3. /** @file
  4. *
  5. * iPXE I/O API
  6. *
  7. * The I/O API provides methods for reading from and writing to
  8. * memory-mapped and I/O-mapped devices.
  9. *
  10. * The standard methods (readl()/writel() etc.) do not strictly check
  11. * the type of the address parameter; this is because traditional
  12. * usage does not necessarily provide the correct pointer type. For
  13. * example, code written for ISA devices at fixed I/O addresses (such
  14. * as the keyboard controller) tend to use plain integer constants for
  15. * the address parameter.
  16. */
  17. FILE_LICENCE ( GPL2_OR_LATER );
  18. #include <stdint.h>
  19. #include <ipxe/api.h>
  20. #include <config/ioapi.h>
  21. #include <ipxe/uaccess.h>
  22. /**
  23. * Calculate static inline I/O API function name
  24. *
  25. * @v _prefix Subsystem prefix
  26. * @v _api_func API function
  27. * @ret _subsys_func Subsystem API function
  28. */
  29. #define IOAPI_INLINE( _subsys, _api_func ) \
  30. SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
  31. /**
  32. * Provide an I/O API implementation
  33. *
  34. * @v _prefix Subsystem prefix
  35. * @v _api_func API function
  36. * @v _func Implementing function
  37. */
  38. #define PROVIDE_IOAPI( _subsys, _api_func, _func ) \
  39. PROVIDE_SINGLE_API ( IOAPI_PREFIX_ ## _subsys, _api_func, _func )
  40. /**
  41. * Provide a static inline I/O API implementation
  42. *
  43. * @v _prefix Subsystem prefix
  44. * @v _api_func API function
  45. */
  46. #define PROVIDE_IOAPI_INLINE( _subsys, _api_func ) \
  47. PROVIDE_SINGLE_API_INLINE ( IOAPI_PREFIX_ ## _subsys, _api_func )
  48. /* Include all architecture-independent I/O API headers */
  49. /* Include all architecture-dependent I/O API headers */
  50. #include <bits/io.h>
  51. /**
  52. * Wrap an I/O read
  53. *
  54. * @v _func I/O API function
  55. * @v _type Data type
  56. * @v io_addr I/O address
  57. * @v _prefix Prefix for address in debug message
  58. * @v _ndigits Number of hex digits for this data type
  59. */
  60. #define IOAPI_READ( _func, _type, io_addr, _prefix, _ndigits ) ( { \
  61. volatile _type *_io_addr = \
  62. ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
  63. _type _data = _func ( _io_addr ); \
  64. DBGIO ( "[" _prefix " %08lx] => %0" #_ndigits "llx\n", \
  65. io_to_bus ( _io_addr ), ( unsigned long long ) _data ); \
  66. _data; } )
  67. /**
  68. * Wrap an I/O write
  69. *
  70. * @v _func I/O API function
  71. * @v _type Data type
  72. * @v data Value to write
  73. * @v io_addr I/O address
  74. * @v _prefix Prefix for address in debug message
  75. * @v _ndigits Number of hex digits for this data type
  76. */
  77. #define IOAPI_WRITE( _func, _type, data, io_addr, _prefix, _ndigits ) do { \
  78. volatile _type *_io_addr = \
  79. ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
  80. _type _data = (data); \
  81. DBGIO ( "[" _prefix " %08lx] <= %0" #_ndigits "llx\n", \
  82. io_to_bus ( _io_addr ), ( unsigned long long ) _data ); \
  83. _func ( _data, _io_addr ); \
  84. } while ( 0 )
  85. /**
  86. * Wrap an I/O string read
  87. *
  88. * @v _func I/O API function
  89. * @v _type Data type
  90. * @v io_addr I/O address
  91. * @v data Data buffer
  92. * @v count Number of elements to read
  93. * @v _prefix Prefix for address in debug message
  94. * @v _ndigits Number of hex digits for this data type
  95. */
  96. #define IOAPI_READS( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
  97. do { \
  98. volatile _type *_io_addr = \
  99. ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
  100. void *_data_void = (data); /* Check data is a pointer */ \
  101. _type * _data = ( ( _type * ) _data_void ); \
  102. const _type * _dbg_data = _data; \
  103. unsigned int _count = (count); \
  104. unsigned int _dbg_count = _count; \
  105. _func ( _io_addr, _data, _count ); \
  106. DBGIO ( "[" _prefix " %08lx] =>", io_to_bus ( _io_addr ) ); \
  107. while ( _dbg_count-- ) { \
  108. DBGIO ( " %0" #_ndigits "llx", \
  109. ( ( unsigned long long ) *(_dbg_data++) ) ); \
  110. } \
  111. DBGIO ( "\n" ); \
  112. } while ( 0 )
  113. /**
  114. * Wrap an I/O string write
  115. *
  116. * @v _func I/O API function
  117. * @v _type Data type
  118. * @v io_addr I/O address
  119. * @v data Data buffer
  120. * @v count Number of elements to write
  121. * @v _prefix Prefix for address in debug message
  122. * @v _ndigits Number of hex digits for this data type
  123. */
  124. #define IOAPI_WRITES( _func, _type, io_addr, data, count, _prefix, _ndigits ) \
  125. do { \
  126. volatile _type *_io_addr = \
  127. ( ( volatile _type * ) ( intptr_t ) (io_addr) ); \
  128. const void *_data_void = (data); /* Check data is a pointer */ \
  129. const _type * _data = ( ( const _type * ) _data_void ); \
  130. const _type * _dbg_data = _data; \
  131. unsigned int _count = (count); \
  132. unsigned int _dbg_count = _count; \
  133. DBGIO ( "[" _prefix " %08lx] <=", io_to_bus ( _io_addr ) ); \
  134. while ( _dbg_count-- ) { \
  135. DBGIO ( " %0" #_ndigits "llx", \
  136. ( ( unsigned long long ) *(_dbg_data++) ) ); \
  137. } \
  138. DBGIO ( "\n" ); \
  139. _func ( _io_addr, _data, _count ); \
  140. } while ( 0 )
  141. /**
  142. * Convert physical address to a bus address
  143. *
  144. * @v phys_addr Physical address
  145. * @ret bus_addr Bus address
  146. */
  147. unsigned long phys_to_bus ( unsigned long phys_addr );
  148. /**
  149. * Convert bus address to a physical address
  150. *
  151. * @v bus_addr Bus address
  152. * @ret phys_addr Physical address
  153. */
  154. unsigned long bus_to_phys ( unsigned long bus_addr );
  155. /**
  156. * Convert virtual address to a bus address
  157. *
  158. * @v addr Virtual address
  159. * @ret bus_addr Bus address
  160. */
  161. static inline __always_inline unsigned long
  162. virt_to_bus ( volatile const void *addr ) {
  163. return phys_to_bus ( virt_to_phys ( addr ) );
  164. }
  165. /**
  166. * Convert bus address to a virtual address
  167. *
  168. * @v bus_addr Bus address
  169. * @ret addr Virtual address
  170. *
  171. * This operation is not available under all memory models.
  172. */
  173. static inline __always_inline void * bus_to_virt ( unsigned long bus_addr ) {
  174. return phys_to_virt ( bus_to_phys ( bus_addr ) );
  175. }
  176. /**
  177. * Map bus address as an I/O address
  178. *
  179. * @v bus_addr Bus address
  180. * @v len Length of region
  181. * @ret io_addr I/O address
  182. */
  183. void * ioremap ( unsigned long bus_addr, size_t len );
  184. /**
  185. * Unmap I/O address
  186. *
  187. * @v io_addr I/O address
  188. */
  189. void iounmap ( volatile const void *io_addr );
  190. /**
  191. * Convert I/O address to bus address (for debug only)
  192. *
  193. * @v io_addr I/O address
  194. * @ret bus_addr Bus address
  195. */
  196. unsigned long io_to_bus ( volatile const void *io_addr );
  197. /**
  198. * Read byte from memory-mapped device
  199. *
  200. * @v io_addr I/O address
  201. * @ret data Value read
  202. */
  203. uint8_t readb ( volatile uint8_t *io_addr );
  204. #define readb( io_addr ) IOAPI_READ ( readb, uint8_t, io_addr, "MEM", 2 )
  205. /**
  206. * Read 16-bit word from memory-mapped device
  207. *
  208. * @v io_addr I/O address
  209. * @ret data Value read
  210. */
  211. uint16_t readw ( volatile uint16_t *io_addr );
  212. #define readw( io_addr ) IOAPI_READ ( readw, uint16_t, io_addr, "MEM", 4 )
  213. /**
  214. * Read 32-bit dword from memory-mapped device
  215. *
  216. * @v io_addr I/O address
  217. * @ret data Value read
  218. */
  219. uint32_t readl ( volatile uint32_t *io_addr );
  220. #define readl( io_addr ) IOAPI_READ ( readl, uint32_t, io_addr, "MEM", 8 )
  221. /**
  222. * Read 64-bit qword from memory-mapped device
  223. *
  224. * @v io_addr I/O address
  225. * @ret data Value read
  226. */
  227. uint64_t readq ( volatile uint64_t *io_addr );
  228. #define readq( io_addr ) IOAPI_READ ( readq, uint64_t, io_addr, "MEM", 16 )
  229. /**
  230. * Write byte to memory-mapped device
  231. *
  232. * @v data Value to write
  233. * @v io_addr I/O address
  234. */
  235. void writeb ( uint8_t data, volatile uint8_t *io_addr );
  236. #define writeb( data, io_addr ) \
  237. IOAPI_WRITE ( writeb, uint8_t, data, io_addr, "MEM", 2 )
  238. /**
  239. * Write 16-bit word to memory-mapped device
  240. *
  241. * @v data Value to write
  242. * @v io_addr I/O address
  243. */
  244. void writew ( uint16_t data, volatile uint16_t *io_addr );
  245. #define writew( data, io_addr ) \
  246. IOAPI_WRITE ( writew, uint16_t, data, io_addr, "MEM", 4 )
  247. /**
  248. * Write 32-bit dword to memory-mapped device
  249. *
  250. * @v data Value to write
  251. * @v io_addr I/O address
  252. */
  253. void writel ( uint32_t data, volatile uint32_t *io_addr );
  254. #define writel( data, io_addr ) \
  255. IOAPI_WRITE ( writel, uint32_t, data, io_addr, "MEM", 8 )
  256. /**
  257. * Write 64-bit qword to memory-mapped device
  258. *
  259. * @v data Value to write
  260. * @v io_addr I/O address
  261. */
  262. void writeq ( uint64_t data, volatile uint64_t *io_addr );
  263. #define writeq( data, io_addr ) \
  264. IOAPI_WRITE ( writeq, uint64_t, data, io_addr, "MEM", 16 )
  265. /**
  266. * Read byte from I/O-mapped device
  267. *
  268. * @v io_addr I/O address
  269. * @ret data Value read
  270. */
  271. uint8_t inb ( volatile uint8_t *io_addr );
  272. #define inb( io_addr ) IOAPI_READ ( inb, uint8_t, io_addr, "IO", 2 )
  273. /**
  274. * Read 16-bit word from I/O-mapped device
  275. *
  276. * @v io_addr I/O address
  277. * @ret data Value read
  278. */
  279. uint16_t inw ( volatile uint16_t *io_addr );
  280. #define inw( io_addr ) IOAPI_READ ( inw, uint16_t, io_addr, "IO", 4 )
  281. /**
  282. * Read 32-bit dword from I/O-mapped device
  283. *
  284. * @v io_addr I/O address
  285. * @ret data Value read
  286. */
  287. uint32_t inl ( volatile uint32_t *io_addr );
  288. #define inl( io_addr ) IOAPI_READ ( inl, uint32_t, io_addr, "IO", 8 )
  289. /**
  290. * Write byte to I/O-mapped device
  291. *
  292. * @v data Value to write
  293. * @v io_addr I/O address
  294. */
  295. void outb ( uint8_t data, volatile uint8_t *io_addr );
  296. #define outb( data, io_addr ) \
  297. IOAPI_WRITE ( outb, uint8_t, data, io_addr, "IO", 2 )
  298. /**
  299. * Write 16-bit word to I/O-mapped device
  300. *
  301. * @v data Value to write
  302. * @v io_addr I/O address
  303. */
  304. void outw ( uint16_t data, volatile uint16_t *io_addr );
  305. #define outw( data, io_addr ) \
  306. IOAPI_WRITE ( outw, uint16_t, data, io_addr, "IO", 4 )
  307. /**
  308. * Write 32-bit dword to I/O-mapped device
  309. *
  310. * @v data Value to write
  311. * @v io_addr I/O address
  312. */
  313. void outl ( uint32_t data, volatile uint32_t *io_addr );
  314. #define outl( data, io_addr ) \
  315. IOAPI_WRITE ( outl, uint32_t, data, io_addr, "IO", 8 )
  316. /**
  317. * Read bytes from I/O-mapped device
  318. *
  319. * @v io_addr I/O address
  320. * @v data Data buffer
  321. * @v count Number of bytes to read
  322. */
  323. void insb ( volatile uint8_t *io_addr, uint8_t *data, unsigned int count );
  324. #define insb( io_addr, data, count ) \
  325. IOAPI_READS ( insb, uint8_t, io_addr, data, count, "IO", 2 )
  326. /**
  327. * Read 16-bit words from I/O-mapped device
  328. *
  329. * @v io_addr I/O address
  330. * @v data Data buffer
  331. * @v count Number of words to read
  332. */
  333. void insw ( volatile uint16_t *io_addr, uint16_t *data, unsigned int count );
  334. #define insw( io_addr, data, count ) \
  335. IOAPI_READS ( insw, uint16_t, io_addr, data, count, "IO", 4 )
  336. /**
  337. * Read 32-bit words from I/O-mapped device
  338. *
  339. * @v io_addr I/O address
  340. * @v data Data buffer
  341. * @v count Number of words to read
  342. */
  343. void insl ( volatile uint32_t *io_addr, uint32_t *data, unsigned int count );
  344. #define insl( io_addr, data, count ) \
  345. IOAPI_READS ( insl, uint32_t, io_addr, data, count, "IO", 8 )
  346. /**
  347. * Write bytes to I/O-mapped device
  348. *
  349. * @v io_addr I/O address
  350. * @v data Data buffer
  351. * @v count Number of bytes to write
  352. */
  353. void outsb ( volatile uint8_t *io_addr, const uint8_t *data,
  354. unsigned int count );
  355. #define outsb( io_addr, data, count ) \
  356. IOAPI_WRITES ( outsb, uint8_t, io_addr, data, count, "IO", 2 )
  357. /**
  358. * Write 16-bit words to I/O-mapped device
  359. *
  360. * @v io_addr I/O address
  361. * @v data Data buffer
  362. * @v count Number of words to write
  363. */
  364. void outsw ( volatile uint16_t *io_addr, const uint16_t *data,
  365. unsigned int count );
  366. #define outsw( io_addr, data, count ) \
  367. IOAPI_WRITES ( outsw, uint16_t, io_addr, data, count, "IO", 4 )
  368. /**
  369. * Write 32-bit words to I/O-mapped device
  370. *
  371. * @v io_addr I/O address
  372. * @v data Data buffer
  373. * @v count Number of words to write
  374. */
  375. void outsl ( volatile uint32_t *io_addr, const uint32_t *data,
  376. unsigned int count );
  377. #define outsl( io_addr, data, count ) \
  378. IOAPI_WRITES ( outsl, uint32_t, io_addr, data, count, "IO", 8 )
  379. /**
  380. * Slow down I/O
  381. *
  382. */
  383. void iodelay ( void );
  384. /**
  385. * Read value from I/O-mapped device, slowly
  386. *
  387. * @v _func Function to use to read value
  388. * @v data Value to write
  389. * @v io_addr I/O address
  390. */
  391. #define INX_P( _func, _type, io_addr ) ( { \
  392. _type _data = _func ( (io_addr) ); \
  393. iodelay(); \
  394. _data; } )
  395. /**
  396. * Read byte from I/O-mapped device
  397. *
  398. * @v io_addr I/O address
  399. * @ret data Value read
  400. */
  401. #define inb_p( io_addr ) INX_P ( inb, uint8_t, io_addr )
  402. /**
  403. * Read 16-bit word from I/O-mapped device
  404. *
  405. * @v io_addr I/O address
  406. * @ret data Value read
  407. */
  408. #define inw_p( io_addr ) INX_P ( inw, uint16_t, io_addr )
  409. /**
  410. * Read 32-bit dword from I/O-mapped device
  411. *
  412. * @v io_addr I/O address
  413. * @ret data Value read
  414. */
  415. #define inl_p( io_addr ) INX_P ( inl, uint32_t, io_addr )
  416. /**
  417. * Write value to I/O-mapped device, slowly
  418. *
  419. * @v _func Function to use to write value
  420. * @v data Value to write
  421. * @v io_addr I/O address
  422. */
  423. #define OUTX_P( _func, data, io_addr ) do { \
  424. _func ( (data), (io_addr) ); \
  425. iodelay(); \
  426. } while ( 0 )
  427. /**
  428. * Write byte to I/O-mapped device, slowly
  429. *
  430. * @v data Value to write
  431. * @v io_addr I/O address
  432. */
  433. #define outb_p( data, io_addr ) OUTX_P ( outb, data, io_addr )
  434. /**
  435. * Write 16-bit word to I/O-mapped device, slowly
  436. *
  437. * @v data Value to write
  438. * @v io_addr I/O address
  439. */
  440. #define outw_p( data, io_addr ) OUTX_P ( outw, data, io_addr )
  441. /**
  442. * Write 32-bit dword to I/O-mapped device, slowly
  443. *
  444. * @v data Value to write
  445. * @v io_addr I/O address
  446. */
  447. #define outl_p( data, io_addr ) OUTX_P ( outl, data, io_addr )
  448. /**
  449. * Memory barrier
  450. *
  451. */
  452. void mb ( void );
  453. #define rmb() mb()
  454. #define wmb() mb()
  455. /** A usable memory region */
  456. struct memory_region {
  457. /** Physical start address */
  458. uint64_t start;
  459. /** Physical end address */
  460. uint64_t end;
  461. };
  462. /** Maximum number of memory regions we expect to encounter */
  463. #define MAX_MEMORY_REGIONS 8
  464. /** A memory map */
  465. struct memory_map {
  466. /** Memory regions */
  467. struct memory_region regions[MAX_MEMORY_REGIONS];
  468. /** Number of used regions */
  469. unsigned int count;
  470. };
  471. /**
  472. * Get memory map
  473. *
  474. * @v memmap Memory map to fill in
  475. */
  476. void get_memmap ( struct memory_map *memmap );
  477. #endif /* _IPXE_IO_H */