00001 #ifndef _GPXE_X86_IO_H
00002 #define _GPXE_X86_IO_H
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 FILE_LICENCE ( GPL2_OR_LATER );
00019
00020 #ifdef IOAPI_X86
00021 #define IOAPI_PREFIX_x86
00022 #else
00023 #define IOAPI_PREFIX_x86 __x86_
00024 #endif
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 static inline __always_inline unsigned long
00037 IOAPI_INLINE ( x86, phys_to_bus ) ( unsigned long phys_addr ) {
00038 return phys_addr;
00039 }
00040
00041 static inline __always_inline unsigned long
00042 IOAPI_INLINE ( x86, bus_to_phys ) ( unsigned long bus_addr ) {
00043 return bus_addr;
00044 }
00045
00046 static inline __always_inline void *
00047 IOAPI_INLINE ( x86, ioremap ) ( unsigned long bus_addr, size_t len __unused ) {
00048 return phys_to_virt ( bus_addr );
00049 }
00050
00051 static inline __always_inline void
00052 IOAPI_INLINE ( x86, iounmap ) ( volatile const void *io_addr __unused ) {
00053
00054 }
00055
00056 static inline __always_inline unsigned long
00057 IOAPI_INLINE ( x86, io_to_bus ) ( volatile const void *io_addr ) {
00058 return virt_to_phys ( io_addr );
00059 }
00060
00061
00062
00063
00064
00065
00066 #define X86_READX( _api_func, _type ) \
00067 static inline __always_inline _type \
00068 IOAPI_INLINE ( x86, _api_func ) ( volatile _type *io_addr ) { \
00069 return *io_addr; \
00070 }
00071 X86_READX ( readb, uint8_t );
00072 X86_READX ( readw, uint16_t );
00073 X86_READX ( readl, uint32_t );
00074
00075 #define X86_WRITEX( _api_func, _type ) \
00076 static inline __always_inline void \
00077 IOAPI_INLINE ( x86, _api_func ) ( _type data, \
00078 volatile _type *io_addr ) { \
00079 *io_addr = data; \
00080 }
00081 X86_WRITEX ( writeb, uint8_t );
00082 X86_WRITEX ( writew, uint16_t );
00083 X86_WRITEX ( writel, uint32_t );
00084
00085
00086
00087
00088
00089
00090 #define X86_INX( _insn_suffix, _type, _reg_prefix ) \
00091 static inline __always_inline _type \
00092 IOAPI_INLINE ( x86, in ## _insn_suffix ) ( volatile _type *io_addr ) { \
00093 _type data; \
00094 __asm__ __volatile__ ( "in" #_insn_suffix " %w1, %" _reg_prefix "0" \
00095 : "=a" ( data ) : "Nd" ( io_addr ) ); \
00096 return data; \
00097 } \
00098 static inline __always_inline void \
00099 IOAPI_INLINE ( x86, ins ## _insn_suffix ) ( volatile _type *io_addr, \
00100 _type *data, \
00101 unsigned int count ) { \
00102 unsigned int discard_D; \
00103 __asm__ __volatile__ ( "rep ins" #_insn_suffix \
00104 : "=D" ( discard_D ) \
00105 : "d" ( io_addr ), "c" ( count ), \
00106 "0" ( data ) ); \
00107 }
00108 X86_INX ( b, uint8_t, "b" );
00109 X86_INX ( w, uint16_t, "w" );
00110 X86_INX ( l, uint32_t, "k" );
00111
00112 #define X86_OUTX( _insn_suffix, _type, _reg_prefix ) \
00113 static inline __always_inline void \
00114 IOAPI_INLINE ( x86, out ## _insn_suffix ) ( _type data, \
00115 volatile _type *io_addr ) { \
00116 __asm__ __volatile__ ( "out" #_insn_suffix " %" _reg_prefix "0, %w1" \
00117 : : "a" ( data ), "Nd" ( io_addr ) ); \
00118 } \
00119 static inline __always_inline void \
00120 IOAPI_INLINE ( x86, outs ## _insn_suffix ) ( volatile _type *io_addr, \
00121 const _type *data, \
00122 unsigned int count ) { \
00123 unsigned int discard_S; \
00124 __asm__ __volatile__ ( "rep outs" #_insn_suffix \
00125 : "=S" ( discard_S ) \
00126 : "d" ( io_addr ), "c" ( count ), \
00127 "0" ( data ) ); \
00128 }
00129 X86_OUTX ( b, uint8_t, "b" );
00130 X86_OUTX ( w, uint16_t, "w" );
00131 X86_OUTX ( l, uint32_t, "k" );
00132
00133
00134
00135
00136
00137
00138 static inline __always_inline void
00139 IOAPI_INLINE ( x86, iodelay ) ( void ) {
00140 __asm__ __volatile__ ( "outb %al, $0x80" );
00141 }
00142
00143
00144
00145
00146
00147
00148 static inline __always_inline void
00149 IOAPI_INLINE ( x86, mb ) ( void ) {
00150 __asm__ __volatile__ ( "lock; addl $0, 0(%%esp)" : : : "memory" );
00151 }
00152
00153 #endif