Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

arm_io.h 2.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. #ifndef _IPXE_ARM_IO_H
  2. #define _IPXE_ARM_IO_H
  3. /** @file
  4. *
  5. * iPXE I/O API for ARM
  6. *
  7. */
  8. FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  9. #ifdef IOAPI_ARM
  10. #define IOAPI_PREFIX_arm
  11. #else
  12. #define IOAPI_PREFIX_arm __arm_
  13. #endif
  14. /*
  15. * Memory space mappings
  16. *
  17. */
  18. /** Page shift */
  19. #define PAGE_SHIFT 12
  20. /*
  21. * Physical<->Bus address mappings
  22. *
  23. */
  24. static inline __always_inline unsigned long
  25. IOAPI_INLINE ( arm, phys_to_bus ) ( unsigned long phys_addr ) {
  26. return phys_addr;
  27. }
  28. static inline __always_inline unsigned long
  29. IOAPI_INLINE ( arm, bus_to_phys ) ( unsigned long bus_addr ) {
  30. return bus_addr;
  31. }
  32. /*
  33. * MMIO reads and writes up to native word size
  34. *
  35. */
  36. #define ARM_READX( _api_func, _type, _insn_suffix, _reg_prefix ) \
  37. static inline __always_inline _type \
  38. IOAPI_INLINE ( arm, _api_func ) ( volatile _type *io_addr ) { \
  39. _type data; \
  40. __asm__ __volatile__ ( "ldr" _insn_suffix " %" _reg_prefix "0, %1" \
  41. : "=r" ( data ) : "Qo" ( *io_addr ) ); \
  42. return data; \
  43. }
  44. #ifdef __aarch64__
  45. ARM_READX ( readb, uint8_t, "b", "w" );
  46. ARM_READX ( readw, uint16_t, "h", "w" );
  47. ARM_READX ( readl, uint32_t, "", "w" );
  48. ARM_READX ( readq, uint64_t, "", "" );
  49. #else
  50. ARM_READX ( readb, uint8_t, "b", "" );
  51. ARM_READX ( readw, uint16_t, "h", "" );
  52. ARM_READX ( readl, uint32_t, "", "" );
  53. #endif
  54. #define ARM_WRITEX( _api_func, _type, _insn_suffix, _reg_prefix ) \
  55. static inline __always_inline void \
  56. IOAPI_INLINE ( arm, _api_func ) ( _type data, volatile _type *io_addr ) { \
  57. __asm__ __volatile__ ( "str" _insn_suffix " %" _reg_prefix "0, %1" \
  58. : : "r" ( data ), "Qo" ( *io_addr ) ); \
  59. }
  60. #ifdef __aarch64__
  61. ARM_WRITEX ( writeb, uint8_t, "b", "w" );
  62. ARM_WRITEX ( writew, uint16_t, "h", "w" );
  63. ARM_WRITEX ( writel, uint32_t, "", "w" );
  64. ARM_WRITEX ( writeq, uint64_t, "", "" );
  65. #else
  66. ARM_WRITEX ( writeb, uint8_t, "b", "" );
  67. ARM_WRITEX ( writew, uint16_t, "h", "" );
  68. ARM_WRITEX ( writel, uint32_t, "", "" );
  69. #endif
  70. /*
  71. * Slow down I/O
  72. *
  73. */
  74. static inline __always_inline void
  75. IOAPI_INLINE ( arm, iodelay ) ( void ) {
  76. /* Nothing to do */
  77. }
  78. /*
  79. * Memory barrier
  80. *
  81. */
  82. static inline __always_inline void
  83. IOAPI_INLINE ( arm, mb ) ( void ) {
  84. #ifdef __aarch64__
  85. __asm__ __volatile__ ( "dmb sy" );
  86. #else
  87. __asm__ __volatile__ ( "dmb" );
  88. #endif
  89. }
  90. #endif /* _IPXE_ARM_IO_H */