romcc_io.h

Go to the documentation of this file.
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; /* pci and pci_mmio need to have different ways to have dev */
00086 
00087 /* FIXME: We need to make the coreboot to run at 64bit mode, So when read/write memory above 4G, 
00088  * We don't need to set %fs, and %gs anymore
00089  * Before that We need to use %gs, and leave %fs to other RAM access
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); //seg == 0
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 /* Generic functions for pnp devices */
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 /* ARCH_ROMCC_IO_H */

Generated on Wed Jan 7 14:14:21 2009 for coreboot by  doxygen 1.5.5