~ubuntu-branches/ubuntu/raring/ipxe/raring

« back to all changes in this revision

Viewing changes to src/arch/x86/include/ipxe/x86_io.h

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2012-11-14 15:47:31 UTC
  • mfrom: (1.1.3)
  • Revision ID: package-import@ubuntu.com-20121114154731-jhuy5d1h2jw75qe9
Tags: 1.0.0+git-4.d6b0b76-0ubuntu1
* New upstream snapshot:
  - d/p/iscsi*.patch: Dropped - included in snapshot.
  - Refreshed all other patches.
* d/p/enable-https.patch: Enable HTTPS support (LP: #1025239).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
/*
 
32
 * Physical<->Bus and Bus<->I/O address mappings
 
33
 *
 
34
 */
 
35
 
 
36
static inline __always_inline unsigned long
 
37
IOAPI_INLINE ( x86, phys_to_bus ) ( unsigned long phys_addr ) {
 
38
        return phys_addr;
 
39
}
 
40
 
 
41
static inline __always_inline unsigned long
 
42
IOAPI_INLINE ( x86, bus_to_phys ) ( unsigned long bus_addr ) {
 
43
        return bus_addr;
 
44
}
 
45
 
 
46
static inline __always_inline void *
 
47
IOAPI_INLINE ( x86, ioremap ) ( unsigned long bus_addr, size_t len __unused ) {
 
48
        return phys_to_virt ( bus_addr );
 
49
}
 
50
 
 
51
static inline __always_inline void
 
52
IOAPI_INLINE ( x86, iounmap ) ( volatile const void *io_addr __unused ) {
 
53
        /* Nothing to do */
 
54
}
 
55
 
 
56
static inline __always_inline unsigned long
 
57
IOAPI_INLINE ( x86, io_to_bus ) ( volatile const void *io_addr ) {
 
58
        return virt_to_phys ( io_addr );
 
59
}
 
60
 
 
61
/*
 
62
 * MMIO reads and writes up to native word size
 
63
 *
 
64
 */
 
65
 
 
66
#define X86_READX( _api_func, _type )                                         \
 
67
static inline __always_inline _type                                           \
 
68
IOAPI_INLINE ( x86, _api_func ) ( volatile _type *io_addr ) {                 \
 
69
        return *io_addr;                                                      \
 
70
}
 
71
X86_READX ( readb, uint8_t );
 
72
X86_READX ( readw, uint16_t );
 
73
X86_READX ( readl, uint32_t );
 
74
#ifdef __x86_64__
 
75
X86_READX ( readq, uint64_t );
 
76
#endif
 
77
 
 
78
#define X86_WRITEX( _api_func, _type )                                        \
 
79
static inline __always_inline void                                            \
 
80
IOAPI_INLINE ( x86, _api_func ) ( _type data,                                 \
 
81
                                  volatile _type *io_addr ) {                 \
 
82
        *io_addr = data;                                                      \
 
83
}
 
84
X86_WRITEX ( writeb, uint8_t );
 
85
X86_WRITEX ( writew, uint16_t );
 
86
X86_WRITEX ( writel, uint32_t );
 
87
#ifdef __x86_64__
 
88
X86_WRITEX ( writeq, uint64_t );
 
89
#endif
 
90
 
 
91
/*
 
92
 * PIO reads and writes up to 32 bits
 
93
 *
 
94
 */
 
95
 
 
96
#define X86_INX( _insn_suffix, _type, _reg_prefix )                           \
 
97
static inline __always_inline _type                                           \
 
98
IOAPI_INLINE ( x86, in ## _insn_suffix ) ( volatile _type *io_addr ) {        \
 
99
        _type data;                                                           \
 
100
        __asm__ __volatile__ ( "in" #_insn_suffix " %w1, %" _reg_prefix "0"   \
 
101
                               : "=a" ( data ) : "Nd" ( io_addr ) );          \
 
102
        return data;                                                          \
 
103
}                                                                             \
 
104
static inline __always_inline void                                            \
 
105
IOAPI_INLINE ( x86, ins ## _insn_suffix ) ( volatile _type *io_addr,          \
 
106
                                            _type *data,                      \
 
107
                                            unsigned int count ) {            \
 
108
        unsigned int discard_D;                                               \
 
109
        __asm__ __volatile__ ( "rep ins" #_insn_suffix                        \
 
110
                               : "=D" ( discard_D )                           \
 
111
                               : "d" ( io_addr ), "c" ( count ),              \
 
112
                                 "0" ( data ) );                              \
 
113
}
 
114
X86_INX ( b, uint8_t, "b" );
 
115
X86_INX ( w, uint16_t, "w" );
 
116
X86_INX ( l, uint32_t, "k" );
 
117
 
 
118
#define X86_OUTX( _insn_suffix, _type, _reg_prefix )                          \
 
119
static inline __always_inline void                                            \
 
120
IOAPI_INLINE ( x86, out ## _insn_suffix ) ( _type data,                       \
 
121
                                            volatile _type *io_addr ) {       \
 
122
        __asm__ __volatile__ ( "out" #_insn_suffix " %" _reg_prefix "0, %w1"  \
 
123
                               : : "a" ( data ), "Nd" ( io_addr ) );          \
 
124
}                                                                             \
 
125
static inline __always_inline void                                            \
 
126
IOAPI_INLINE ( x86, outs ## _insn_suffix ) ( volatile _type *io_addr,         \
 
127
                                             const _type *data,               \
 
128
                                             unsigned int count ) {           \
 
129
        unsigned int discard_S;                                               \
 
130
        __asm__ __volatile__ ( "rep outs" #_insn_suffix                       \
 
131
                               : "=S" ( discard_S )                           \
 
132
                               : "d" ( io_addr ), "c" ( count ),              \
 
133
                                 "0" ( data ) );                              \
 
134
}
 
135
X86_OUTX ( b, uint8_t, "b" );
 
136
X86_OUTX ( w, uint16_t, "w" );
 
137
X86_OUTX ( l, uint32_t, "k" );
 
138
 
 
139
/*
 
140
 * Slow down I/O
 
141
 *
 
142
 */
 
143
 
 
144
static inline __always_inline void
 
145
IOAPI_INLINE ( x86, iodelay ) ( void ) {
 
146
        __asm__ __volatile__ ( "outb %al, $0x80" );
 
147
}
 
148
 
 
149
/*
 
150
 * Memory barrier
 
151
 *
 
152
 */
 
153
 
 
154
static inline __always_inline void
 
155
IOAPI_INLINE ( x86, mb ) ( void ) {
 
156
        __asm__ __volatile__ ( "lock; addl $0, 0(%%esp)" : : : "memory" );
 
157
}
 
158
 
 
159
#endif /* _IPXE_X86_IO_H */