iPXE
x86_io.h
Go to the documentation of this file.
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
18FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
19FILE_SECBOOT ( PERMITTED );
20
21#ifdef IOAPI_X86
22#define IOAPI_PREFIX_x86
23#else
24#define IOAPI_PREFIX_x86 __x86_
25#endif
26
27/*
28 * Memory space mappings
29 *
30 */
31
32/*
33 * Physical<->Bus address mappings
34 *
35 */
36
37static inline __always_inline unsigned long
38IOAPI_INLINE ( x86, phys_to_bus ) ( unsigned long phys_addr ) {
39 return phys_addr;
40}
41
42static inline __always_inline unsigned long
43IOAPI_INLINE ( x86, bus_to_phys ) ( unsigned long bus_addr ) {
44 return bus_addr;
45}
46
47/*
48 * MMIO reads and writes up to native word size
49 *
50 */
51
52#define X86_READX( _api_func, _type ) \
53static inline __always_inline _type \
54IOAPI_INLINE ( x86, _api_func ) ( volatile _type *io_addr ) { \
55 return *io_addr; \
56}
60#ifdef __x86_64__
62#endif
63
64#define X86_WRITEX( _api_func, _type ) \
65static inline __always_inline void \
66IOAPI_INLINE ( x86, _api_func ) ( _type data, \
67 volatile _type *io_addr ) { \
68 *io_addr = data; \
69}
73#ifdef __x86_64__
75#endif
76
77/*
78 * PIO reads and writes up to 32 bits
79 *
80 */
81
82#define X86_INX( _insn_suffix, _type, _reg_prefix ) \
83static inline __always_inline _type \
84IOAPI_INLINE ( x86, in ## _insn_suffix ) ( volatile _type *io_addr ) { \
85 _type data; \
86 __asm__ __volatile__ ( "in" #_insn_suffix " %w1, %" _reg_prefix "0" \
87 : "=a" ( data ) : "Nd" ( io_addr ) ); \
88 return data; \
89} \
90static inline __always_inline void \
91IOAPI_INLINE ( x86, ins ## _insn_suffix ) ( volatile _type *io_addr, \
92 _type *data, \
93 unsigned int count ) { \
94 unsigned int discard_D; \
95 __asm__ __volatile__ ( "rep ins" #_insn_suffix \
96 : "=D" ( discard_D ) \
97 : "d" ( io_addr ), "c" ( count ), \
98 "0" ( data ) ); \
99}
100X86_INX ( b, uint8_t, "b" );
101X86_INX ( w, uint16_t, "w" );
103
104#define X86_OUTX( _insn_suffix, _type, _reg_prefix ) \
105static inline __always_inline void \
106IOAPI_INLINE ( x86, out ## _insn_suffix ) ( _type data, \
107 volatile _type *io_addr ) { \
108 __asm__ __volatile__ ( "out" #_insn_suffix " %" _reg_prefix "0, %w1" \
109 : : "a" ( data ), "Nd" ( io_addr ) ); \
110} \
111static inline __always_inline void \
112IOAPI_INLINE ( x86, outs ## _insn_suffix ) ( volatile _type *io_addr, \
113 const _type *data, \
114 unsigned int count ) { \
115 unsigned int discard_S; \
116 __asm__ __volatile__ ( "rep outs" #_insn_suffix \
117 : "=S" ( discard_S ) \
118 : "d" ( io_addr ), "c" ( count ), \
119 "0" ( data ) ); \
120}
121X86_OUTX ( b, uint8_t, "b" );
122X86_OUTX ( w, uint16_t, "w" );
124
125/*
126 * Slow down I/O
127 *
128 */
129
130static inline __always_inline void
131IOAPI_INLINE ( x86, iodelay ) ( void ) {
132 __asm__ __volatile__ ( "outb %al, $0x80" );
133}
134
135/*
136 * Memory barrier
137 *
138 */
139
140static inline __always_inline void
141IOAPI_INLINE ( x86, mb ) ( void ) {
142 __asm__ __volatile__ ( "lock; addl $0, 0(%%esp)" : : : "memory" );
143}
144
145#endif /* _IPXE_X86_IO_H */
__asm__ __volatile__("call *%9" :"=a"(result), "=c"(discard_ecx), "=d"(discard_edx) :"d"(0), "a"(code), "b"(0), "c"(in_phys), "D"(0), "S"(out_phys), "m"(hypercall))
unsigned short uint16_t
Definition stdint.h:11
unsigned int uint32_t
Definition stdint.h:12
unsigned long long uint64_t
Definition stdint.h:13
unsigned char uint8_t
Definition stdint.h:10
#define __always_inline
Declare a function to be always inline.
Definition compiler.h:611
#define FILE_LICENCE(_licence)
Declare a particular licence as applying to a file.
Definition compiler.h:896
#define FILE_SECBOOT(_status)
Declare a file's UEFI Secure Boot permission status.
Definition compiler.h:926
#define IOAPI_INLINE(_subsys, _api_func)
Calculate static inline I/O API function name.
Definition io.h:40
void mb(void)
Memory barrier.
unsigned long phys_to_bus(unsigned long phys_addr)
Convert physical address to a bus address.
void iodelay(void)
Slow down I/O.
unsigned long bus_to_phys(unsigned long bus_addr)
Convert bus address to a physical address.
#define readq(io_addr)
Definition io.h:234
#define writeq(data, io_addr)
Definition io.h:273
static __always_inline void unsigned long bus_addr
Definition pcibios.h:156
__asm__(".section \".rodata\", \"a\", " PROGBITS "\n\t" "\nprivate_key_data:\n\t" ".size private_key_data, ( . - private_key_data )\n\t" ".equ private_key_len, ( . - private_key_data )\n\t" ".previous\n\t")
uint8_t l
Definition registers.h:1
#define readl
Definition w89c840.c:157
#define writel
Definition w89c840.c:160
#define writew
Definition w89c840.c:159
#define readb
Definition w89c840.c:155
#define writeb
Definition w89c840.c:158
#define readw
Definition w89c840.c:156
#define X86_WRITEX(_api_func, _type)
Definition x86_io.h:64
#define X86_INX(_insn_suffix, _type, _reg_prefix)
Definition x86_io.h:82
#define X86_OUTX(_insn_suffix, _type, _reg_prefix)
Definition x86_io.h:104
#define X86_READX(_api_func, _type)
Definition x86_io.h:52