1 #ifndef ARCH_ROMCC_IO_H
2 #define ARCH_ROMCC_IO_H 1
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>
10 #if CONFIG_MMCONF_SUPPORT
12 #include <arch/mmio_conf.h>
16 static inline int log2(int value)
24 : "=r" (r) : "r" (value));
28 static inline int log2f(int value)
36 : "=r" (r) : "r" (value));
41 #define PCI_ADDR(SEGBUS, DEV, FN, WHERE) ( \
42 (((SEGBUS) & 0xFFF) << 20) | \
43 (((DEV) & 0x1F) << 15) | \
44 (((FN) & 0x07) << 12) | \
47 #define PCI_DEV(SEGBUS, DEV, FN) ( \
48 (((SEGBUS) & 0xFFF) << 20) | \
49 (((DEV) & 0x1F) << 15) | \
50 (((FN) & 0x07) << 12))
52 #define PCI_ID(VENDOR_ID, DEVICE_ID) \
53 ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
56 #define PNP_DEV(PORT, FUNC) (((PORT) << 8) | (FUNC))
58 typedef unsigned device_t; /* pci and pci_mmio need to have different ways to have dev */
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
65 static inline __attribute__((always_inline)) uint8_t pci_io_read_config8(device_t dev, unsigned where)
68 #if CONFIG_PCI_IO_CFG_EXT == 0
69 addr = (dev>>4) | where;
71 addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16); //seg == 0
73 outl(0x80000000 | (addr & ~3), 0xCF8);
74 return inb(0xCFC + (addr & 3));
77 #if CONFIG_MMCONF_SUPPORT
78 static inline __attribute__((always_inline)) uint8_t pci_mmio_read_config8(device_t dev, unsigned where)
81 addr = CONFIG_MMCONF_BASE_ADDRESS | dev | where;
85 static inline __attribute__((always_inline)) uint8_t pci_read_config8(device_t dev, unsigned where)
87 #if CONFIG_MMCONF_SUPPORT_DEFAULT
88 return pci_mmio_read_config8(dev, where);
90 return pci_io_read_config8(dev, where);
94 static inline __attribute__((always_inline)) uint16_t pci_io_read_config16(device_t dev, unsigned where)
97 #if CONFIG_PCI_IO_CFG_EXT == 0
98 addr = (dev>>4) | where;
100 addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16);
102 outl(0x80000000 | (addr & ~3), 0xCF8);
103 return inw(0xCFC + (addr & 2));
106 #if CONFIG_MMCONF_SUPPORT
107 static inline __attribute__((always_inline)) uint16_t pci_mmio_read_config16(device_t dev, unsigned where)
110 addr = CONFIG_MMCONF_BASE_ADDRESS | dev | (where & ~1);
111 return read16x(addr);
115 static inline __attribute__((always_inline)) uint16_t pci_read_config16(device_t dev, unsigned where)
117 #if CONFIG_MMCONF_SUPPORT_DEFAULT
118 return pci_mmio_read_config16(dev, where);
120 return pci_io_read_config16(dev, where);
125 static inline __attribute__((always_inline)) uint32_t pci_io_read_config32(device_t dev, unsigned where)
128 #if CONFIG_PCI_IO_CFG_EXT == 0
129 addr = (dev>>4) | where;
131 addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16);
133 outl(0x80000000 | (addr & ~3), 0xCF8);
137 #if CONFIG_MMCONF_SUPPORT
138 static inline __attribute__((always_inline)) uint32_t pci_mmio_read_config32(device_t dev, unsigned where)
141 addr = CONFIG_MMCONF_BASE_ADDRESS | dev | (where & ~3);
142 return read32x(addr);
146 static inline __attribute__((always_inline)) uint32_t pci_read_config32(device_t dev, unsigned where)
148 #if CONFIG_MMCONF_SUPPORT_DEFAULT
149 return pci_mmio_read_config32(dev, where);
151 return pci_io_read_config32(dev, where);
155 static inline __attribute__((always_inline)) void pci_io_write_config8(device_t dev, unsigned where, uint8_t value)
158 #if CONFIG_PCI_IO_CFG_EXT == 0
159 addr = (dev>>4) | where;
161 addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16);
163 outl(0x80000000 | (addr & ~3), 0xCF8);
164 outb(value, 0xCFC + (addr & 3));
167 #if CONFIG_MMCONF_SUPPORT
168 static inline __attribute__((always_inline)) void pci_mmio_write_config8(device_t dev, unsigned where, uint8_t value)
171 addr = CONFIG_MMCONF_BASE_ADDRESS | dev | where;
172 write8x(addr, value);
176 static inline __attribute__((always_inline)) void pci_write_config8(device_t dev, unsigned where, uint8_t value)
178 #if CONFIG_MMCONF_SUPPORT_DEFAULT
179 pci_mmio_write_config8(dev, where, value);
181 pci_io_write_config8(dev, where, value);
186 static inline __attribute__((always_inline)) void pci_io_write_config16(device_t dev, unsigned where, uint16_t value)
189 #if CONFIG_PCI_IO_CFG_EXT == 0
190 addr = (dev>>4) | where;
192 addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16);
194 outl(0x80000000 | (addr & ~3), 0xCF8);
195 outw(value, 0xCFC + (addr & 2));
198 #if CONFIG_MMCONF_SUPPORT
199 static inline __attribute__((always_inline)) void pci_mmio_write_config16(device_t dev, unsigned where, uint16_t value)
202 addr = CONFIG_MMCONF_BASE_ADDRESS | dev | (where & ~1);
203 write16x(addr, value);
207 static inline __attribute__((always_inline)) void pci_write_config16(device_t dev, unsigned where, uint16_t value)
209 #if CONFIG_MMCONF_SUPPORT_DEFAULT
210 pci_mmio_write_config16(dev, where, value);
212 pci_io_write_config16(dev, where, value);
217 static inline __attribute__((always_inline)) void pci_io_write_config32(device_t dev, unsigned where, uint32_t value)
220 #if CONFIG_PCI_IO_CFG_EXT == 0
221 addr = (dev>>4) | where;
223 addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16);
225 outl(0x80000000 | (addr & ~3), 0xCF8);
229 #if CONFIG_MMCONF_SUPPORT
230 static inline __attribute__((always_inline)) void pci_mmio_write_config32(device_t dev, unsigned where, uint32_t value)
233 addr = CONFIG_MMCONF_BASE_ADDRESS | dev | (where & ~3);
234 write32x(addr, value);
238 static inline __attribute__((always_inline)) void pci_write_config32(device_t dev, unsigned where, uint32_t value)
240 #if CONFIG_MMCONF_SUPPORT_DEFAULT
241 pci_mmio_write_config32(dev, where, value);
243 pci_io_write_config32(dev, where, value);
247 #define PCI_DEV_INVALID (0xffffffffU)
248 static inline device_t pci_io_locate_device(unsigned pci_id, device_t dev)
250 for(; dev <= PCI_DEV(255, 31, 7); dev += PCI_DEV(0,0,1)) {
252 id = pci_io_read_config32(dev, 0);
257 return PCI_DEV_INVALID;
260 static inline device_t pci_locate_device(unsigned pci_id, device_t dev)
262 for(; dev <= PCI_DEV(255|(((1<<CONFIG_PCI_BUS_SEGN_BITS)-1)<<8), 31, 7); dev += PCI_DEV(0,0,1)) {
264 id = pci_read_config32(dev, 0);
269 return PCI_DEV_INVALID;
272 static inline device_t pci_locate_device_on_bus(unsigned pci_id, unsigned bus)
276 dev = PCI_DEV(bus, 0, 0);
277 last = PCI_DEV(bus, 31, 7);
279 for(; dev <=last; dev += PCI_DEV(0,0,1)) {
281 id = pci_read_config32(dev, 0);
286 return PCI_DEV_INVALID;
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)
292 unsigned port = dev >> 8;
294 outb(value, port +1);
297 static inline __attribute__((always_inline)) uint8_t pnp_read_config(device_t dev, uint8_t reg)
299 unsigned port = dev >> 8;
304 static inline __attribute__((always_inline)) void pnp_set_logical_device(device_t dev)
306 unsigned device = dev & 0xff;
307 pnp_write_config(dev, 0x07, device);
310 static inline __attribute__((always_inline)) void pnp_set_enable(device_t dev, int enable)
312 pnp_write_config(dev, 0x30, enable?0x1:0x0);
315 static inline __attribute__((always_inline)) int pnp_read_enable(device_t dev)
317 return !!pnp_read_config(dev, 0x30);
320 static inline __attribute__((always_inline)) void pnp_set_iobase(device_t dev, unsigned index, unsigned iobase)
322 pnp_write_config(dev, index + 0, (iobase >> 8) & 0xff);
323 pnp_write_config(dev, index + 1, iobase & 0xff);
326 static inline __attribute__((always_inline)) uint16_t pnp_read_iobase(device_t dev, unsigned index)
328 return ((uint16_t)(pnp_read_config(dev, index)) << 8) | pnp_read_config(dev, index + 1);
331 static inline __attribute__((always_inline)) void pnp_set_irq(device_t dev, unsigned index, unsigned irq)
333 pnp_write_config(dev, index, irq);
336 static inline __attribute__((always_inline)) void pnp_set_drq(device_t dev, unsigned index, unsigned drq)
338 pnp_write_config(dev, index, drq & 0xff);
341 #endif /* ARCH_ROMCC_IO_H */