After this has been brought up many times before, rename src/arch/i386 to
[coreboot.git] / src / arch / x86 / include / arch / io.h
1 #ifndef _ASM_IO_H
2 #define _ASM_IO_H
3
4 #include <stdint.h>
5
6 /*
7  * This file contains the definitions for the x86 IO instructions
8  * inb/inw/inl/outb/outw/outl and the "string versions" of the same
9  * (insb/insw/insl/outsb/outsw/outsl). You can also use "pausing"
10  * versions of the single-IO instructions (inb_p/inw_p/..).
11  */
12 #if defined(__ROMCC__)
13 static inline void outb(uint8_t value, uint16_t port)
14 {
15         __builtin_outb(value, port);
16 }
17
18 static inline void outw(uint16_t value, uint16_t port)
19 {
20         __builtin_outw(value, port);
21 }
22
23 static inline void outl(uint32_t value, uint16_t port)
24 {
25         __builtin_outl(value, port);
26 }
27
28
29 static inline uint8_t inb(uint16_t port)
30 {
31         return __builtin_inb(port);
32 }
33
34
35 static inline uint16_t inw(uint16_t port)
36 {
37         return __builtin_inw(port);
38 }
39
40 static inline uint32_t inl(uint16_t port)
41 {
42         return __builtin_inl(port);
43 }
44 #else
45 static inline void outb(uint8_t value, uint16_t port)
46 {
47         __asm__ __volatile__ ("outb %b0, %w1" : : "a" (value), "Nd" (port));
48 }
49
50 static inline void outw(uint16_t value, uint16_t port)
51 {
52         __asm__ __volatile__ ("outw %w0, %w1" : : "a" (value), "Nd" (port));
53 }
54
55 static inline void outl(uint32_t value, uint16_t port)
56 {
57         __asm__ __volatile__ ("outl %0, %w1" : : "a" (value), "Nd" (port));
58 }
59
60 static inline uint8_t inb(uint16_t port)
61 {
62         uint8_t value;
63         __asm__ __volatile__ ("inb %w1, %b0" : "=a"(value) : "Nd" (port));
64         return value;
65 }
66
67 static inline uint16_t inw(uint16_t port)
68 {
69         uint16_t value;
70         __asm__ __volatile__ ("inw %w1, %w0" : "=a"(value) : "Nd" (port));
71         return value;
72 }
73
74 static inline uint32_t inl(uint16_t port)
75 {
76         uint32_t value;
77         __asm__ __volatile__ ("inl %w1, %0" : "=a"(value) : "Nd" (port));
78         return value;
79 }
80 #endif /* __ROMCC__ */
81
82 static inline void outsb(uint16_t port, const void *addr, unsigned long count)
83 {
84         __asm__ __volatile__ (
85                 "cld ; rep ; outsb "
86                 : "=S" (addr), "=c" (count)
87                 : "d"(port), "0"(addr), "1" (count)
88                 );
89 }
90
91 static inline void outsw(uint16_t port, const void *addr, unsigned long count)
92 {
93         __asm__ __volatile__ (
94                 "cld ; rep ; outsw "
95                 : "=S" (addr), "=c" (count)
96                 : "d"(port), "0"(addr), "1" (count)
97                 );
98 }
99
100 static inline void outsl(uint16_t port, const void *addr, unsigned long count)
101 {
102         __asm__ __volatile__ (
103                 "cld ; rep ; outsl "
104                 : "=S" (addr), "=c" (count)
105                 : "d"(port), "0"(addr), "1" (count)
106                 );
107 }
108
109
110 static inline void insb(uint16_t port, void *addr, unsigned long count)
111 {
112         __asm__ __volatile__ (
113                 "cld ; rep ; insb "
114                 : "=D" (addr), "=c" (count)
115                 : "d"(port), "0"(addr), "1" (count)
116                 );
117 }
118
119 static inline void insw(uint16_t port, void *addr, unsigned long count)
120 {
121         __asm__ __volatile__ (
122                 "cld ; rep ; insw "
123                 : "=D" (addr), "=c" (count)
124                 : "d"(port), "0"(addr), "1" (count)
125                 );
126 }
127
128 static inline void insl(uint16_t port, void *addr, unsigned long count)
129 {
130         __asm__ __volatile__ (
131                 "cld ; rep ; insl "
132                 : "=D" (addr), "=c" (count)
133                 : "d"(port), "0"(addr), "1" (count)
134                 );
135 }
136
137 static inline __attribute__((always_inline)) uint8_t read8(unsigned long addr)
138 {
139         return *((volatile uint8_t *)(addr));
140 }
141
142 static inline __attribute__((always_inline)) uint16_t read16(unsigned long addr)
143 {
144         return *((volatile uint16_t *)(addr));
145 }
146
147 static inline __attribute__((always_inline)) uint32_t read32(unsigned long addr)
148 {
149         return *((volatile uint32_t *)(addr));
150 }
151
152 static inline __attribute__((always_inline)) void write8(unsigned long addr, uint8_t value)
153 {
154         *((volatile uint8_t *)(addr)) = value;
155 }
156
157 static inline __attribute__((always_inline)) void write16(unsigned long addr, uint16_t value)
158 {
159         *((volatile uint16_t *)(addr)) = value;
160 }
161
162 static inline __attribute__((always_inline)) void write32(unsigned long addr, uint32_t value)
163 {
164         *((volatile uint32_t *)(addr)) = value;
165 }
166
167 #endif
168