00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _IOMACROS_H_
00019 #define _IOMACROS_H_
00020
00021 #include <inttypes.h>
00022
00023 #ifndef BV
00024 #define BV(x) (1 << (x))
00025 #endif
00026
00027
00028
00029 #define __mmio(port) (*((volatile uint8_t *)((uint8_t)(port) + 0x20)))
00030
00031
00032
00033 #define __inb(port) ({ \
00034 uint8_t __t; \
00035 __asm__ __volatile__ ( \
00036 "in %0,%1" \
00037 : "=r" (__t) \
00038 : "I" ((uint8_t)(port)) \
00039 ); \
00040 __t; \
00041 })
00042
00043
00044
00045
00046
00047 #define __outb(val, port) \
00048 __asm__ __volatile__ ( \
00049 "out %1,%0" \
00050 : \
00051 : "r" ((uint8_t)(val)), \
00052 "I" ((uint8_t)(port)) \
00053 )
00054
00055 #define __outb_zero(port) \
00056 __asm__ __volatile__ ( \
00057 "out %0,__zero_reg__" \
00058 : \
00059 : "I" ((uint8_t)(port)) \
00060 )
00061
00062
00063
00064 #define inp(port) (__builtin_constant_p((port)) ? __inb((port)) : __mmio((port)))
00065
00066 #define outp(val,port) do { \
00067 if (__builtin_constant_p((port))) { \
00068 if (__builtin_constant_p((val)) && ((val) == 0)) \
00069 __outb_zero((port)); \
00070 else \
00071 __outb((val), (port)); \
00072 } else \
00073 __mmio((port)) = (val); \
00074 } while (0)
00075
00076
00077
00078
00079
00080
00081
00082
00083 #define __inw(port) ({ \
00084 uint16_t __t; \
00085 __asm__ __volatile__ ( \
00086 "in %A0,%1" "\n\t" \
00087 "in %B0,(%1)+1" \
00088 : "=r" (__t) \
00089 : "I" ((uint8_t)(port)) \
00090 ); \
00091 __t; \
00092 })
00093
00094 #define __inw_atomic(port) ({ \
00095 uint16_t __t; \
00096 __asm__ __volatile__ ( \
00097 "in __tmp_reg__,__SREG__" "\n\t" \
00098 "cli" "\n\t" \
00099 "in %A0,%1" "\n\t" \
00100 "out __SREG__,__tmp_reg__" "\n\t" \
00101 "in %B0,(%1)+1" \
00102 : "=r" (__t) \
00103 : "I" ((uint8_t)(port)) \
00104 : "r0" \
00105 ); \
00106 __t; \
00107 })
00108
00109 #define __outw(val, port) \
00110 __asm__ __volatile__ ( \
00111 "out (%1)+1,%B0" "\n\t" \
00112 "out %1,%A0" \
00113 : \
00114 : "r" ((uint16_t)(val)), \
00115 "I" ((uint8_t)(port)) \
00116 )
00117
00118 #define __outw_atomic(val, port) \
00119 __asm__ __volatile__ ( \
00120 "in __tmp_reg__,__SREG__" "\n\t" \
00121 "cli" "\n\t" \
00122 "out (%1)+1,%B0" "\n\t" \
00123 "out __SREG__,__tmp_reg__" "\n\t" \
00124 "out %1,%A0" \
00125 : \
00126 : "r" ((uint16_t)(val)), \
00127 "I" ((uint8_t)(port)) \
00128 : "r0" \
00129 )
00130
00131
00132
00133 #define __cbi(port, bit) \
00134 __asm__ __volatile__ ( \
00135 "cbi %0,%1" \
00136 : \
00137 : "I" ((uint8_t)(port)), \
00138 "I" ((uint8_t)(bit)) \
00139 )
00140
00141 #define __sbi(port, bit) \
00142 __asm__ __volatile__ ( \
00143 "sbi %0,%1" \
00144 : \
00145 : "I" ((uint8_t)(port)), \
00146 "I" ((uint8_t)(bit)) \
00147 )
00148
00149
00150
00151 #define __port_and(port, val) \
00152 __asm__ __volatile__ ( \
00153 "in __tmp_reg__,%0" "\n\t" \
00154 "and __tmp_reg__,%1" "\n\t" \
00155 "out %0,__tmp_reg__" \
00156 : \
00157 : "I" ((uint8_t)(port)), \
00158 "r" ((uint8_t)(val)) \
00159 : "r0" \
00160 )
00161
00162 #define __port_or(port, val) \
00163 __asm__ __volatile__ ( \
00164 "in __tmp_reg__,%0" "\n\t" \
00165 "or __tmp_reg__,%1" "\n\t" \
00166 "out %0,__tmp_reg__" \
00167 : \
00168 : "I" ((uint8_t)(port)), \
00169 "r" ((uint8_t)(val)) \
00170 : "r0" \
00171 )
00172
00173
00174
00175 #define __cbi_const_port(port, bit) do { \
00176 if (((port) < 0x20) && __builtin_constant_p((bit))) \
00177 __cbi((port), (bit)); \
00178 else \
00179 __port_and((port), ~BV((bit))); \
00180 } while (0)
00181
00182 #define __sbi_const_port(port, bit) do { \
00183 if (((port) < 0x20) && __builtin_constant_p((bit))) \
00184 __sbi((port), (bit)); \
00185 else \
00186 __port_or((port), BV((bit))); \
00187 } while (0)
00188
00189
00190
00191 #define cbi(port, bit) do { \
00192 if (__builtin_constant_p((port))) \
00193 __cbi_const_port((port), (bit)); \
00194 else \
00195 __mmio((port)) &= ~BV((bit)); \
00196 } while (0)
00197
00198 #define sbi(port, bit) do { \
00199 if (__builtin_constant_p((port))) \
00200 __sbi_const_port((port), (bit)); \
00201 else \
00202 __mmio((port)) |= BV((bit)); \
00203 } while (0)
00204
00205 #if 1
00206
00207
00208 #define bit_is_set(port, bit) (__inb(port) & (1<<(bit)))
00209 #define bit_is_clear(port, bit) (!bit_is_set(port, bit))
00210
00211 #else
00212
00213 #define bit_is_clear(port, bit) ({ \
00214 uint8_t __t; \
00215 __asm__ __volatile__ ( \
00216 "clr %0" "\n\t" \
00217 "sbis %1,%2" "\n\t" \
00218 "inc %0" \
00219 : "=r" (__t) \
00220 : "I" ((uint8_t)(port)), \
00221 "I" ((uint8_t)(bit)) \
00222 ); \
00223 __t; \
00224 })
00225
00226 #define bit_is_set(port, bit) ({ \
00227 uint8_t __t; \
00228 __asm__ __volatile__ ( \
00229 "clr %0" "\n\t" \
00230 "sbic %1,%2" "\n\t" \
00231 "inc %0" \
00232 : "=r" (__t) \
00233 : "I" ((uint8_t)(port)), \
00234 "I" ((uint8_t)(bit)) \
00235 ); \
00236 __t; \
00237 })
00238
00239 #endif
00240
00241 #define loop_until_bit_is_set(port, bit) \
00242 __asm__ __volatile__ ( \
00243 "L_%=: " "sbis %0,%1" "\n\t" \
00244 "rjmp L_%=" \
00245 : \
00246 : "I" ((uint8_t)(port)), \
00247 "I" ((uint8_t)(bit)) \
00248 )
00249
00250 #define loop_until_bit_is_clear(port, bit) \
00251 __asm__ __volatile__ ( \
00252 "L_%=: " "sbic %0,%1" "\n\t" \
00253 "rjmp L_%=" \
00254 : \
00255 : "I" ((uint8_t)(port)), \
00256 "I" ((uint8_t)(bit)) \
00257 )
00258
00259 #define parity_even_bit(val) ({ \
00260 uint8_t __t; \
00261 __asm__ ( \
00262 "mov __tmp_reg__,%0" "\n\t" \
00263 "swap %0" "\n\t" \
00264 "eor %0,__tmp_reg__" "\n\t" \
00265 "mov __tmp_reg__,%0" "\n\t" \
00266 "lsr %0" "\n\t" \
00267 "lsr %0" "\n\t" \
00268 "eor %0,__tmp_reg__" "\n\t" \
00269 "mov __tmp_reg__,%0" "\n\t" \
00270 "lsr %0" "\n\t" \
00271 "eor %0,__tmp_reg__" \
00272 : "=r" (__t) \
00273 : "0" ((uint8_t)(val)) \
00274 : "r0" \
00275 ); \
00276 (__t & 1); \
00277 })
00278
00279 #endif