00001 #ifndef ARCH_ROMCC_IO_H
00002 #define ARCH_ROMCC_IO_H 1
00003
00004 #include <stdint.h>
00005
00006
00007 static inline __attribute__((always_inline)) uint8_t read8(unsigned long addr)
00008 {
00009 return *((volatile uint8_t *)(addr));
00010 }
00011
00012 static inline __attribute__((always_inline)) uint16_t read16(unsigned long addr)
00013 {
00014 return *((volatile uint16_t *)(addr));
00015 }
00016
00017 static inline __attribute__((always_inline)) uint32_t read32(unsigned long addr)
00018 {
00019 return *((volatile uint32_t *)(addr));
00020 }
00021
00022 static inline __attribute__((always_inline)) void write8(unsigned long addr, uint8_t value)
00023 {
00024 *((volatile uint8_t *)(addr)) = value;
00025 }
00026
00027 static inline __attribute__((always_inline)) void write16(unsigned long addr, uint16_t value)
00028 {
00029 *((volatile uint16_t *)(addr)) = value;
00030 }
00031
00032 static inline __attribute__((always_inline)) void write32(unsigned long addr, uint32_t value)
00033 {
00034 *((volatile uint32_t *)(addr)) = value;
00035 }
00036
00037 #if MMCONF_SUPPORT
00038
00039 #include <arch/mmio_conf.h>
00040
00041 #endif
00042
00043 static inline int log2(int value)
00044 {
00045 unsigned int r = 0;
00046 __asm__ volatile (
00047 "bsrl %1, %0\n\t"
00048 "jnz 1f\n\t"
00049 "movl $-1, %0\n\t"
00050 "1:\n\t"
00051 : "=r" (r) : "r" (value));
00052 return r;
00053
00054 }
00055 static inline int log2f(int value)
00056 {
00057 unsigned int r = 0;
00058 __asm__ volatile (
00059 "bsfl %1, %0\n\t"
00060 "jnz 1f\n\t"
00061 "movl $-1, %0\n\t"
00062 "1:\n\t"
00063 : "=r" (r) : "r" (value));
00064 return r;
00065
00066 }
00067
00068 #define PCI_ADDR(SEGBUS, DEV, FN, WHERE) ( \
00069 (((SEGBUS) & 0xFFF) << 20) | \
00070 (((DEV) & 0x1F) << 15) | \
00071 (((FN) & 0x07) << 12) | \
00072 ((WHERE) & 0xFFF))
00073
00074 #define PCI_DEV(SEGBUS, DEV, FN) ( \
00075 (((SEGBUS) & 0xFFF) << 20) | \
00076 (((DEV) & 0x1F) << 15) | \
00077 (((FN) & 0x07) << 12))
00078
00079 #define PCI_ID(VENDOR_ID, DEVICE_ID) \
00080 ((((DEVICE_ID) & 0xFFFF) << 16) | ((VENDOR_ID) & 0xFFFF))
00081
00082
00083 #define PNP_DEV(PORT, FUNC) (((PORT) << 8) | (FUNC))
00084
00085 typedef unsigned device_t;
00086
00087
00088
00089
00090
00091
00092 static inline __attribute__((always_inline)) uint8_t pci_io_read_config8(device_t dev, unsigned where)
00093 {
00094 unsigned addr;
00095 #if PCI_IO_CFG_EXT == 0
00096 addr = (dev>>4) | where;
00097 #else
00098 addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16);
00099 #endif
00100 outl(0x80000000 | (addr & ~3), 0xCF8);
00101 return inb(0xCFC + (addr & 3));
00102 }
00103
00104 #if MMCONF_SUPPORT
00105 static inline __attribute__((always_inline)) uint8_t pci_mmio_read_config8(device_t dev, unsigned where)
00106 {
00107 unsigned addr;
00108 addr = dev | where;
00109 return read8x(addr);
00110 }
00111 #endif
00112 static inline __attribute__((always_inline)) uint8_t pci_read_config8(device_t dev, unsigned where)
00113 {
00114 #if MMCONF_SUPPORT
00115 return pci_mmio_read_config8(dev, where);
00116 #else
00117 return pci_io_read_config8(dev, where);
00118 #endif
00119 }
00120
00121 static inline __attribute__((always_inline)) uint16_t pci_io_read_config16(device_t dev, unsigned where)
00122 {
00123 unsigned addr;
00124 #if PCI_IO_CFG_EXT == 0
00125 addr = (dev>>4) | where;
00126 #else
00127 addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16);
00128 #endif
00129 outl(0x80000000 | (addr & ~3), 0xCF8);
00130 return inw(0xCFC + (addr & 2));
00131 }
00132
00133 #if MMCONF_SUPPORT
00134 static inline __attribute__((always_inline)) uint16_t pci_mmio_read_config16(device_t dev, unsigned where)
00135 {
00136 unsigned addr;
00137 addr = dev | where;
00138 return read16x(addr);
00139 }
00140 #endif
00141
00142 static inline __attribute__((always_inline)) uint16_t pci_read_config16(device_t dev, unsigned where)
00143 {
00144 #if MMCONF_SUPPORT
00145 return pci_mmio_read_config16(dev, where);
00146 #else
00147 return pci_io_read_config16(dev, where);
00148 #endif
00149 }
00150
00151
00152 static inline __attribute__((always_inline)) uint32_t pci_io_read_config32(device_t dev, unsigned where)
00153 {
00154 unsigned addr;
00155 #if PCI_IO_CFG_EXT == 0
00156 addr = (dev>>4) | where;
00157 #else
00158 addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16);
00159 #endif
00160 outl(0x80000000 | (addr & ~3), 0xCF8);
00161 return inl(0xCFC);
00162 }
00163
00164 #if MMCONF_SUPPORT
00165 static inline __attribute__((always_inline)) uint32_t pci_mmio_read_config32(device_t dev, unsigned where)
00166 {
00167 unsigned addr;
00168 addr = dev | where;
00169 return read32x(addr);
00170 }
00171 #endif
00172
00173 static inline __attribute__((always_inline)) uint32_t pci_read_config32(device_t dev, unsigned where)
00174 {
00175 #if MMCONF_SUPPORT
00176 return pci_mmio_read_config32(dev, where);
00177 #else
00178 return pci_io_read_config32(dev, where);
00179 #endif
00180 }
00181
00182 static inline __attribute__((always_inline)) void pci_io_write_config8(device_t dev, unsigned where, uint8_t value)
00183 {
00184 unsigned addr;
00185 #if PCI_IO_CFG_EXT == 0
00186 addr = (dev>>4) | where;
00187 #else
00188 addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16);
00189 #endif
00190 outl(0x80000000 | (addr & ~3), 0xCF8);
00191 outb(value, 0xCFC + (addr & 3));
00192 }
00193
00194 #if MMCONF_SUPPORT
00195 static inline __attribute__((always_inline)) void pci_mmio_write_config8(device_t dev, unsigned where, uint8_t value)
00196 {
00197 unsigned addr;
00198 addr = dev | where;
00199 write8x(addr, value);
00200 }
00201 #endif
00202
00203 static inline __attribute__((always_inline)) void pci_write_config8(device_t dev, unsigned where, uint8_t value)
00204 {
00205 #if MMCONF_SUPPORT
00206 pci_mmio_write_config8(dev, where, value);
00207 #else
00208 pci_io_write_config8(dev, where, value);
00209 #endif
00210 }
00211
00212
00213 static inline __attribute__((always_inline)) void pci_io_write_config16(device_t dev, unsigned where, uint16_t value)
00214 {
00215 unsigned addr;
00216 #if PCI_IO_CFG_EXT == 0
00217 addr = (dev>>4) | where;
00218 #else
00219 addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16);
00220 #endif
00221 outl(0x80000000 | (addr & ~3), 0xCF8);
00222 outw(value, 0xCFC + (addr & 2));
00223 }
00224
00225 #if MMCONF_SUPPORT
00226 static inline __attribute__((always_inline)) void pci_mmio_write_config16(device_t dev, unsigned where, uint16_t value)
00227 {
00228 unsigned addr;
00229 addr = dev | where;
00230 write16x(addr, value);
00231 }
00232 #endif
00233
00234 static inline __attribute__((always_inline)) void pci_write_config16(device_t dev, unsigned where, uint16_t value)
00235 {
00236 #if MMCONF_SUPPORT
00237 pci_mmio_write_config16(dev, where, value);
00238 #else
00239 pci_io_write_config16(dev, where, value);
00240 #endif
00241 }
00242
00243
00244 static inline __attribute__((always_inline)) void pci_io_write_config32(device_t dev, unsigned where, uint32_t value)
00245 {
00246 unsigned addr;
00247 #if PCI_IO_CFG_EXT == 0
00248 addr = (dev>>4) | where;
00249 #else
00250 addr = (dev>>4) | (where & 0xff) | ((where & 0xf00)<<16);
00251 #endif
00252 outl(0x80000000 | (addr & ~3), 0xCF8);
00253 outl(value, 0xCFC);
00254 }
00255
00256 #if MMCONF_SUPPORT
00257 static inline __attribute__((always_inline)) void pci_mmio_write_config32(device_t dev, unsigned where, uint32_t value)
00258 {
00259 unsigned addr;
00260 addr = dev | where;
00261 write32x(addr, value);
00262 }
00263 #endif
00264
00265 static inline __attribute__((always_inline)) void pci_write_config32(device_t dev, unsigned where, uint32_t value)
00266 {
00267 #if MMCONF_SUPPORT
00268 pci_mmio_write_config32(dev, where, value);
00269 #else
00270 pci_io_write_config32(dev, where, value);
00271 #endif
00272 }
00273
00274 #define PCI_DEV_INVALID (0xffffffffU)
00275 static device_t pci_io_locate_device(unsigned pci_id, device_t dev)
00276 {
00277 for(; dev <= PCI_DEV(255, 31, 7); dev += PCI_DEV(0,0,1)) {
00278 unsigned int id;
00279 id = pci_io_read_config32(dev, 0);
00280 if (id == pci_id) {
00281 return dev;
00282 }
00283 }
00284 return PCI_DEV_INVALID;
00285 }
00286
00287 static device_t pci_locate_device(unsigned pci_id, device_t dev)
00288 {
00289 for(; dev <= PCI_DEV(255|(((1<<PCI_BUS_SEGN_BITS)-1)<<8), 31, 7); dev += PCI_DEV(0,0,1)) {
00290 unsigned int id;
00291 id = pci_read_config32(dev, 0);
00292 if (id == pci_id) {
00293 return dev;
00294 }
00295 }
00296 return PCI_DEV_INVALID;
00297 }
00298
00299 static device_t pci_locate_device_on_bus(unsigned pci_id, unsigned bus)
00300 {
00301 device_t dev, last;
00302
00303 dev = PCI_DEV(bus, 0, 0);
00304 last = PCI_DEV(bus, 31, 7);
00305
00306 for(; dev <=last; dev += PCI_DEV(0,0,1)) {
00307 unsigned int id;
00308 id = pci_read_config32(dev, 0);
00309 if (id == pci_id) {
00310 return dev;
00311 }
00312 }
00313 return PCI_DEV_INVALID;
00314 }
00315
00316
00317 static inline __attribute__((always_inline)) void pnp_write_config(device_t dev, uint8_t reg, uint8_t value)
00318 {
00319 unsigned port = dev >> 8;
00320 outb(reg, port );
00321 outb(value, port +1);
00322 }
00323
00324 static inline __attribute__((always_inline)) uint8_t pnp_read_config(device_t dev, uint8_t reg)
00325 {
00326 unsigned port = dev >> 8;
00327 outb(reg, port);
00328 return inb(port +1);
00329 }
00330
00331 static inline __attribute__((always_inline)) void pnp_set_logical_device(device_t dev)
00332 {
00333 unsigned device = dev & 0xff;
00334 pnp_write_config(dev, 0x07, device);
00335 }
00336
00337 static inline __attribute__((always_inline)) void pnp_set_enable(device_t dev, int enable)
00338 {
00339 pnp_write_config(dev, 0x30, enable?0x1:0x0);
00340 }
00341
00342 static inline __attribute__((always_inline)) int pnp_read_enable(device_t dev)
00343 {
00344 return !!pnp_read_config(dev, 0x30);
00345 }
00346
00347 static inline __attribute__((always_inline)) void pnp_set_iobase(device_t dev, unsigned index, unsigned iobase)
00348 {
00349 pnp_write_config(dev, index + 0, (iobase >> 8) & 0xff);
00350 pnp_write_config(dev, index + 1, iobase & 0xff);
00351 }
00352
00353 static inline __attribute__((always_inline)) uint16_t pnp_read_iobase(device_t dev, unsigned index)
00354 {
00355 return ((uint16_t)(pnp_read_config(dev, index)) << 8) | pnp_read_config(dev, index + 1);
00356 }
00357
00358 static inline __attribute__((always_inline)) void pnp_set_irq(device_t dev, unsigned index, unsigned irq)
00359 {
00360 pnp_write_config(dev, index, irq);
00361 }
00362
00363 static inline __attribute__((always_inline)) void pnp_set_drq(device_t dev, unsigned index, unsigned drq)
00364 {
00365 pnp_write_config(dev, index, drq & 0xff);
00366 }
00367
00368 #endif