Add qemu 2.4.0
[kvmfornfv.git] / qemu / roms / ipxe / src / arch / x86 / include / ipxe / x86_io.h
1 #ifndef _IPXE_X86_IO_H
2 #define _IPXE_X86_IO_H
3
4 /** @file
5  *
6  * iPXE I/O API for x86
7  *
8  * x86 uses direct pointer dereferences for accesses to memory-mapped
9  * I/O space, and the inX/outX instructions for accesses to
10  * port-mapped I/O space.
11  *
12  * 64-bit atomic accesses (readq() and writeq()) use MMX instructions
13  * under i386, and will crash original Pentium and earlier CPUs.
14  * Fortunately, no hardware that requires atomic 64-bit accesses will
15  * physically fit into a machine with such an old CPU anyway.
16  */
17
18 FILE_LICENCE ( GPL2_OR_LATER );
19
20 #ifdef IOAPI_X86
21 #define IOAPI_PREFIX_x86
22 #else
23 #define IOAPI_PREFIX_x86 __x86_
24 #endif
25
26 /*
27  * Memory space mappings
28  *
29  */
30
31 /** Page shift */
32 #define PAGE_SHIFT 12
33
34 /*
35  * Physical<->Bus and Bus<->I/O address mappings
36  *
37  */
38
39 static inline __always_inline unsigned long
40 IOAPI_INLINE ( x86, phys_to_bus ) ( unsigned long phys_addr ) {
41         return phys_addr;
42 }
43
44 static inline __always_inline unsigned long
45 IOAPI_INLINE ( x86, bus_to_phys ) ( unsigned long bus_addr ) {
46         return bus_addr;
47 }
48
49 static inline __always_inline void *
50 IOAPI_INLINE ( x86, ioremap ) ( unsigned long bus_addr, size_t len __unused ) {
51         return ( bus_addr ? phys_to_virt ( bus_addr ) : NULL );
52 }
53
54 static inline __always_inline void
55 IOAPI_INLINE ( x86, iounmap ) ( volatile const void *io_addr __unused ) {
56         /* Nothing to do */
57 }
58
59 static inline __always_inline unsigned long
60 IOAPI_INLINE ( x86, io_to_bus ) ( volatile const void *io_addr ) {
61         return virt_to_phys ( io_addr );
62 }
63
64 /*
65  * MMIO reads and writes up to native word size
66  *
67  */
68
69 #define X86_READX( _api_func, _type )                                         \
70 static inline __always_inline _type                                           \
71 IOAPI_INLINE ( x86, _api_func ) ( volatile _type *io_addr ) {                 \
72         return *io_addr;                                                      \
73 }
74 X86_READX ( readb, uint8_t );
75 X86_READX ( readw, uint16_t );
76 X86_READX ( readl, uint32_t );
77 #ifdef __x86_64__
78 X86_READX ( readq, uint64_t );
79 #endif
80
81 #define X86_WRITEX( _api_func, _type )                                        \
82 static inline __always_inline void                                            \
83 IOAPI_INLINE ( x86, _api_func ) ( _type data,                                 \
84                                   volatile _type *io_addr ) {                 \
85         *io_addr = data;                                                      \
86 }
87 X86_WRITEX ( writeb, uint8_t );
88 X86_WRITEX ( writew, uint16_t );
89 X86_WRITEX ( writel, uint32_t );
90 #ifdef __x86_64__
91 X86_WRITEX ( writeq, uint64_t );
92 #endif
93
94 /*
95  * PIO reads and writes up to 32 bits
96  *
97  */
98
99 #define X86_INX( _insn_suffix, _type, _reg_prefix )                           \
100 static inline __always_inline _type                                           \
101 IOAPI_INLINE ( x86, in ## _insn_suffix ) ( volatile _type *io_addr ) {        \
102         _type data;                                                           \
103         __asm__ __volatile__ ( "in" #_insn_suffix " %w1, %" _reg_prefix "0"   \
104                                : "=a" ( data ) : "Nd" ( io_addr ) );          \
105         return data;                                                          \
106 }                                                                             \
107 static inline __always_inline void                                            \
108 IOAPI_INLINE ( x86, ins ## _insn_suffix ) ( volatile _type *io_addr,          \
109                                             _type *data,                      \
110                                             unsigned int count ) {            \
111         unsigned int discard_D;                                               \
112         __asm__ __volatile__ ( "rep ins" #_insn_suffix                        \
113                                : "=D" ( discard_D )                           \
114                                : "d" ( io_addr ), "c" ( count ),              \
115                                  "0" ( data ) );                              \
116 }
117 X86_INX ( b, uint8_t, "b" );
118 X86_INX ( w, uint16_t, "w" );
119 X86_INX ( l, uint32_t, "k" );
120
121 #define X86_OUTX( _insn_suffix, _type, _reg_prefix )                          \
122 static inline __always_inline void                                            \
123 IOAPI_INLINE ( x86, out ## _insn_suffix ) ( _type data,                       \
124                                             volatile _type *io_addr ) {       \
125         __asm__ __volatile__ ( "out" #_insn_suffix " %" _reg_prefix "0, %w1"  \
126                                : : "a" ( data ), "Nd" ( io_addr ) );          \
127 }                                                                             \
128 static inline __always_inline void                                            \
129 IOAPI_INLINE ( x86, outs ## _insn_suffix ) ( volatile _type *io_addr,         \
130                                              const _type *data,               \
131                                              unsigned int count ) {           \
132         unsigned int discard_S;                                               \
133         __asm__ __volatile__ ( "rep outs" #_insn_suffix                       \
134                                : "=S" ( discard_S )                           \
135                                : "d" ( io_addr ), "c" ( count ),              \
136                                  "0" ( data ) );                              \
137 }
138 X86_OUTX ( b, uint8_t, "b" );
139 X86_OUTX ( w, uint16_t, "w" );
140 X86_OUTX ( l, uint32_t, "k" );
141
142 /*
143  * Slow down I/O
144  *
145  */
146
147 static inline __always_inline void
148 IOAPI_INLINE ( x86, iodelay ) ( void ) {
149         __asm__ __volatile__ ( "outb %al, $0x80" );
150 }
151
152 /*
153  * Memory barrier
154  *
155  */
156
157 static inline __always_inline void
158 IOAPI_INLINE ( x86, mb ) ( void ) {
159         __asm__ __volatile__ ( "lock; addl $0, 0(%%esp)" : : : "memory" );
160 }
161
162 #endif /* _IPXE_X86_IO_H */