remove trailing whitespace
[coreboot.git] / src / arch / x86 / include / arch / romcc_io.h
1 #ifndef ARCH_ROMCC_IO_H
2 #define ARCH_ROMCC_IO_H 1
3
4 #include <stdint.h>
5
6 // arch/io.h is pulled in in many places but it could
7 // also be pulled in here for all romcc/romstage code.
8 // #include <arch/io.h>
9
10 #if CONFIG_MMCONF_SUPPORT
11
12 #include <arch/mmio_conf.h>
13
14 #endif
15
16 static inline int log2(int value)
17 {
18         unsigned int r = 0;
19         __asm__ volatile (
20                 "bsrl %1, %0\n\t"
21                 "jnz 1f\n\t"
22                 "movl $-1, %0\n\t"
23                 "1:\n\t"
24                 : "=r" (r) : "r" (value));
25         return r;
26
27 }
28 static inline int log2f(int value)
29 {
30         unsigned int r = 0;
31         __asm__ volatile (
32                 "bsfl %1, %0\n\t"
33                 "jnz 1f\n\t"
34                 "movl $-1, %0\n\t"
35                 "1:\n\t"
36                 : "=r" (r) : "r" (value));
37         return r;
38
39 }
40
41 #define PCI_ADDR(SEGBUS, DEV, FN, WHERE) ( \
42         (((SEGBUS) & 0xFFF) << 20) | \
43         (((DEV) & 0x1F) << 15) | \
44         (((FN) & 0x07) << 12) | \
45         ((WHERE) & 0xFFF))
46
47 #define PCI_DEV(SEGBUS, DEV, FN) ( \
48         (((SEGBUS) & 0xFFF) << 20) | \
49         (((DEV) & 0x1F) << 15) | \
50         (((FN)  & 0x07) << 12))
51
52 #define PCI_ID(VENDOR_ID, DEVICE_ID) \
53         ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
54
55
56 #define PNP_DEV(PORT, FUNC) (((PORT) << 8) | (FUNC))
57
58 typedef unsigned device_t; /* pci and pci_mmio need to have different ways to have dev */
59
60 /* FIXME: We need to make the coreboot to run at 64bit mode, So when read/write memory above 4G,
61  * We don't need to set %fs, and %gs anymore
62  * Before that We need to use %gs, and leave %fs to other RAM access
63  */
64
65 static inline __attribute__((always_inline)) uint8_t pci_io_read_config8(device_t dev, unsigned where)
66 {
67         unsigned addr;
68 #if CONFIG_PCI_IO_CFG_EXT == 0
69         addr = (dev>>4) | where;
70 #else
71         addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16); //seg == 0
72 #endif
73         outl(0x80000000 | (addr & ~3), 0xCF8);
74         return inb(0xCFC + (addr & 3));
75 }
76
77 #if CONFIG_MMCONF_SUPPORT
78 static inline __attribute__((always_inline)) uint8_t pci_mmio_read_config8(device_t dev, unsigned where)
79 {
80         unsigned addr;
81         addr = CONFIG_MMCONF_BASE_ADDRESS | dev | where;
82         return read8x(addr);
83 }
84 #endif
85 static inline __attribute__((always_inline)) uint8_t pci_read_config8(device_t dev, unsigned where)
86 {
87 #if CONFIG_MMCONF_SUPPORT_DEFAULT
88         return pci_mmio_read_config8(dev, where);
89 #else
90         return pci_io_read_config8(dev, where);
91 #endif
92 }
93
94 static inline __attribute__((always_inline)) uint16_t pci_io_read_config16(device_t dev, unsigned where)
95 {
96         unsigned addr;
97 #if CONFIG_PCI_IO_CFG_EXT == 0
98         addr = (dev>>4) | where;
99 #else
100         addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16);
101 #endif
102         outl(0x80000000 | (addr & ~3), 0xCF8);
103         return inw(0xCFC + (addr & 2));
104 }
105
106 #if CONFIG_MMCONF_SUPPORT
107 static inline __attribute__((always_inline)) uint16_t pci_mmio_read_config16(device_t dev, unsigned where)
108 {
109         unsigned addr;
110         addr = CONFIG_MMCONF_BASE_ADDRESS | dev | (where & ~1);
111         return read16x(addr);
112 }
113 #endif
114
115 static inline __attribute__((always_inline)) uint16_t pci_read_config16(device_t dev, unsigned where)
116 {
117 #if CONFIG_MMCONF_SUPPORT_DEFAULT
118         return pci_mmio_read_config16(dev, where);
119 #else
120         return pci_io_read_config16(dev, where);
121 #endif
122 }
123
124
125 static inline __attribute__((always_inline)) uint32_t pci_io_read_config32(device_t dev, unsigned where)
126 {
127         unsigned addr;
128 #if CONFIG_PCI_IO_CFG_EXT == 0
129         addr = (dev>>4) | where;
130 #else
131         addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16);
132 #endif
133         outl(0x80000000 | (addr & ~3), 0xCF8);
134         return inl(0xCFC);
135 }
136
137 #if CONFIG_MMCONF_SUPPORT
138 static inline __attribute__((always_inline)) uint32_t pci_mmio_read_config32(device_t dev, unsigned where)
139 {
140         unsigned addr;
141         addr = CONFIG_MMCONF_BASE_ADDRESS | dev | (where & ~3);
142         return read32x(addr);
143 }
144 #endif
145
146 static inline __attribute__((always_inline)) uint32_t pci_read_config32(device_t dev, unsigned where)
147 {
148 #if CONFIG_MMCONF_SUPPORT_DEFAULT
149         return pci_mmio_read_config32(dev, where);
150 #else
151         return pci_io_read_config32(dev, where);
152 #endif
153 }
154
155 static inline __attribute__((always_inline)) void pci_io_write_config8(device_t dev, unsigned where, uint8_t value)
156 {
157         unsigned addr;
158 #if CONFIG_PCI_IO_CFG_EXT == 0
159         addr = (dev>>4) | where;
160 #else
161         addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16);
162 #endif
163         outl(0x80000000 | (addr & ~3), 0xCF8);
164         outb(value, 0xCFC + (addr & 3));
165 }
166
167 #if CONFIG_MMCONF_SUPPORT
168 static inline __attribute__((always_inline)) void pci_mmio_write_config8(device_t dev, unsigned where, uint8_t value)
169 {
170         unsigned addr;
171         addr = CONFIG_MMCONF_BASE_ADDRESS | dev | where;
172         write8x(addr, value);
173 }
174 #endif
175
176 static inline __attribute__((always_inline)) void pci_write_config8(device_t dev, unsigned where, uint8_t value)
177 {
178 #if CONFIG_MMCONF_SUPPORT_DEFAULT
179         pci_mmio_write_config8(dev, where, value);
180 #else
181         pci_io_write_config8(dev, where, value);
182 #endif
183 }
184
185
186 static inline __attribute__((always_inline)) void pci_io_write_config16(device_t dev, unsigned where, uint16_t value)
187 {
188         unsigned addr;
189 #if CONFIG_PCI_IO_CFG_EXT == 0
190         addr = (dev>>4) | where;
191 #else
192         addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16);
193 #endif
194         outl(0x80000000 | (addr & ~3), 0xCF8);
195         outw(value, 0xCFC + (addr & 2));
196 }
197
198 #if CONFIG_MMCONF_SUPPORT
199 static inline __attribute__((always_inline)) void pci_mmio_write_config16(device_t dev, unsigned where, uint16_t value)
200 {
201         unsigned addr;
202         addr = CONFIG_MMCONF_BASE_ADDRESS | dev | (where & ~1);
203         write16x(addr, value);
204 }
205 #endif
206
207 static inline __attribute__((always_inline)) void pci_write_config16(device_t dev, unsigned where, uint16_t value)
208 {
209 #if CONFIG_MMCONF_SUPPORT_DEFAULT
210         pci_mmio_write_config16(dev, where, value);
211 #else
212         pci_io_write_config16(dev, where, value);
213 #endif
214 }
215
216
217 static inline __attribute__((always_inline)) void pci_io_write_config32(device_t dev, unsigned where, uint32_t value)
218 {
219         unsigned addr;
220 #if CONFIG_PCI_IO_CFG_EXT == 0
221         addr = (dev>>4) | where;
222 #else
223         addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16);
224 #endif
225         outl(0x80000000 | (addr & ~3), 0xCF8);
226         outl(value, 0xCFC);
227 }
228
229 #if CONFIG_MMCONF_SUPPORT
230 static inline __attribute__((always_inline)) void pci_mmio_write_config32(device_t dev, unsigned where, uint32_t value)
231 {
232         unsigned addr;
233         addr = CONFIG_MMCONF_BASE_ADDRESS | dev | (where & ~3);
234         write32x(addr, value);
235 }
236 #endif
237
238 static inline __attribute__((always_inline)) void pci_write_config32(device_t dev, unsigned where, uint32_t value)
239 {
240 #if CONFIG_MMCONF_SUPPORT_DEFAULT
241         pci_mmio_write_config32(dev, where, value);
242 #else
243         pci_io_write_config32(dev, where, value);
244 #endif
245 }
246
247 #define PCI_DEV_INVALID (0xffffffffU)
248 static inline device_t pci_io_locate_device(unsigned pci_id, device_t dev)
249 {
250         for(; dev <= PCI_DEV(255, 31, 7); dev += PCI_DEV(0,0,1)) {
251                 unsigned int id;
252                 id = pci_io_read_config32(dev, 0);
253                 if (id == pci_id) {
254                         return dev;
255                 }
256         }
257         return PCI_DEV_INVALID;
258 }
259
260 static inline device_t pci_locate_device(unsigned pci_id, device_t dev)
261 {
262         for(; dev <= PCI_DEV(255|(((1<<CONFIG_PCI_BUS_SEGN_BITS)-1)<<8), 31, 7); dev += PCI_DEV(0,0,1)) {
263                 unsigned int id;
264                 id = pci_read_config32(dev, 0);
265                 if (id == pci_id) {
266                         return dev;
267                 }
268         }
269         return PCI_DEV_INVALID;
270 }
271
272 static inline device_t pci_locate_device_on_bus(unsigned pci_id, unsigned bus)
273 {
274         device_t dev, last;
275
276         dev = PCI_DEV(bus, 0, 0);
277         last = PCI_DEV(bus, 31, 7);
278
279         for(; dev <=last; dev += PCI_DEV(0,0,1)) {
280                 unsigned int id;
281                 id = pci_read_config32(dev, 0);
282                 if (id == pci_id) {
283                         return dev;
284                 }
285         }
286         return PCI_DEV_INVALID;
287 }
288
289 /* Generic functions for pnp devices */
290 static inline __attribute__((always_inline)) void pnp_write_config(device_t dev, uint8_t reg, uint8_t value)
291 {
292         unsigned port = dev >> 8;
293         outb(reg, port );
294         outb(value, port +1);
295 }
296
297 static inline __attribute__((always_inline)) uint8_t pnp_read_config(device_t dev, uint8_t reg)
298 {
299         unsigned port = dev >> 8;
300         outb(reg, port);
301         return inb(port +1);
302 }
303
304 static inline __attribute__((always_inline)) void pnp_set_logical_device(device_t dev)
305 {
306         unsigned device = dev & 0xff;
307         pnp_write_config(dev, 0x07, device);
308 }
309
310 static inline __attribute__((always_inline)) void pnp_set_enable(device_t dev, int enable)
311 {
312         pnp_write_config(dev, 0x30, enable?0x1:0x0);
313 }
314
315 static inline __attribute__((always_inline)) int pnp_read_enable(device_t dev)
316 {
317         return !!pnp_read_config(dev, 0x30);
318 }
319
320 static inline __attribute__((always_inline)) void pnp_set_iobase(device_t dev, unsigned index, unsigned iobase)
321 {
322         pnp_write_config(dev, index + 0, (iobase >> 8) & 0xff);
323         pnp_write_config(dev, index + 1, iobase & 0xff);
324 }
325
326 static inline __attribute__((always_inline)) uint16_t pnp_read_iobase(device_t dev, unsigned index)
327 {
328         return ((uint16_t)(pnp_read_config(dev, index)) << 8) | pnp_read_config(dev, index + 1);
329 }
330
331 static inline __attribute__((always_inline)) void pnp_set_irq(device_t dev, unsigned index, unsigned irq)
332 {
333         pnp_write_config(dev, index, irq);
334 }
335
336 static inline __attribute__((always_inline)) void pnp_set_drq(device_t dev, unsigned index, unsigned drq)
337 {
338         pnp_write_config(dev, index, drq & 0xff);
339 }
340
341 #endif /* ARCH_ROMCC_IO_H */