linux/arch/x86/pci/direct.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * direct.c - Low-level direct PCI config space access
   4 */
   5
   6#include <linux/pci.h>
   7#include <linux/init.h>
   8#include <linux/dmi.h>
   9#include <asm/pci_x86.h>
  10
  11/*
  12 * Functions for accessing PCI base (first 256 bytes) and extended
  13 * (4096 bytes per PCI function) configuration space with type 1
  14 * accesses.
  15 */
  16
  17#define PCI_CONF1_ADDRESS(bus, devfn, reg) \
  18        (0x80000000 | ((reg & 0xF00) << 16) | (bus << 16) \
  19        | (devfn << 8) | (reg & 0xFC))
  20
  21static int pci_conf1_read(unsigned int seg, unsigned int bus,
  22                          unsigned int devfn, int reg, int len, u32 *value)
  23{
  24        unsigned long flags;
  25
  26        if (seg || (bus > 255) || (devfn > 255) || (reg > 4095)) {
  27                *value = -1;
  28                return -EINVAL;
  29        }
  30
  31        raw_spin_lock_irqsave(&pci_config_lock, flags);
  32
  33        outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8);
  34
  35        switch (len) {
  36        case 1:
  37                *value = inb(0xCFC + (reg & 3));
  38                break;
  39        case 2:
  40                *value = inw(0xCFC + (reg & 2));
  41                break;
  42        case 4:
  43                *value = inl(0xCFC);
  44                break;
  45        }
  46
  47        raw_spin_unlock_irqrestore(&pci_config_lock, flags);
  48
  49        return 0;
  50}
  51
  52static int pci_conf1_write(unsigned int seg, unsigned int bus,
  53                           unsigned int devfn, int reg, int len, u32 value)
  54{
  55        unsigned long flags;
  56
  57        if (seg || (bus > 255) || (devfn > 255) || (reg > 4095))
  58                return -EINVAL;
  59
  60        raw_spin_lock_irqsave(&pci_config_lock, flags);
  61
  62        outl(PCI_CONF1_ADDRESS(bus, devfn, reg), 0xCF8);
  63
  64        switch (len) {
  65        case 1:
  66                outb((u8)value, 0xCFC + (reg & 3));
  67                break;
  68        case 2:
  69                outw((u16)value, 0xCFC + (reg & 2));
  70                break;
  71        case 4:
  72                outl((u32)value, 0xCFC);
  73                break;
  74        }
  75
  76        raw_spin_unlock_irqrestore(&pci_config_lock, flags);
  77
  78        return 0;
  79}
  80
  81#undef PCI_CONF1_ADDRESS
  82
  83const struct pci_raw_ops pci_direct_conf1 = {
  84        .read =         pci_conf1_read,
  85        .write =        pci_conf1_write,
  86};
  87
  88
  89/*
  90 * Functions for accessing PCI configuration space with type 2 accesses
  91 */
  92
  93#define PCI_CONF2_ADDRESS(dev, reg)     (u16)(0xC000 | (dev << 8) | reg)
  94
  95static int pci_conf2_read(unsigned int seg, unsigned int bus,
  96                          unsigned int devfn, int reg, int len, u32 *value)
  97{
  98        unsigned long flags;
  99        int dev, fn;
 100
 101        WARN_ON(seg);
 102        if ((bus > 255) || (devfn > 255) || (reg > 255)) {
 103                *value = -1;
 104                return -EINVAL;
 105        }
 106
 107        dev = PCI_SLOT(devfn);
 108        fn = PCI_FUNC(devfn);
 109
 110        if (dev & 0x10) 
 111                return PCIBIOS_DEVICE_NOT_FOUND;
 112
 113        raw_spin_lock_irqsave(&pci_config_lock, flags);
 114
 115        outb((u8)(0xF0 | (fn << 1)), 0xCF8);
 116        outb((u8)bus, 0xCFA);
 117
 118        switch (len) {
 119        case 1:
 120                *value = inb(PCI_CONF2_ADDRESS(dev, reg));
 121                break;
 122        case 2:
 123                *value = inw(PCI_CONF2_ADDRESS(dev, reg));
 124                break;
 125        case 4:
 126                *value = inl(PCI_CONF2_ADDRESS(dev, reg));
 127                break;
 128        }
 129
 130        outb(0, 0xCF8);
 131
 132        raw_spin_unlock_irqrestore(&pci_config_lock, flags);
 133
 134        return 0;
 135}
 136
 137static int pci_conf2_write(unsigned int seg, unsigned int bus,
 138                           unsigned int devfn, int reg, int len, u32 value)
 139{
 140        unsigned long flags;
 141        int dev, fn;
 142
 143        WARN_ON(seg);
 144        if ((bus > 255) || (devfn > 255) || (reg > 255)) 
 145                return -EINVAL;
 146
 147        dev = PCI_SLOT(devfn);
 148        fn = PCI_FUNC(devfn);
 149
 150        if (dev & 0x10) 
 151                return PCIBIOS_DEVICE_NOT_FOUND;
 152
 153        raw_spin_lock_irqsave(&pci_config_lock, flags);
 154
 155        outb((u8)(0xF0 | (fn << 1)), 0xCF8);
 156        outb((u8)bus, 0xCFA);
 157
 158        switch (len) {
 159        case 1:
 160                outb((u8)value, PCI_CONF2_ADDRESS(dev, reg));
 161                break;
 162        case 2:
 163                outw((u16)value, PCI_CONF2_ADDRESS(dev, reg));
 164                break;
 165        case 4:
 166                outl((u32)value, PCI_CONF2_ADDRESS(dev, reg));
 167                break;
 168        }
 169
 170        outb(0, 0xCF8);    
 171
 172        raw_spin_unlock_irqrestore(&pci_config_lock, flags);
 173
 174        return 0;
 175}
 176
 177#undef PCI_CONF2_ADDRESS
 178
 179static const struct pci_raw_ops pci_direct_conf2 = {
 180        .read =         pci_conf2_read,
 181        .write =        pci_conf2_write,
 182};
 183
 184
 185/*
 186 * Before we decide to use direct hardware access mechanisms, we try to do some
 187 * trivial checks to ensure it at least _seems_ to be working -- we just test
 188 * whether bus 00 contains a host bridge (this is similar to checking
 189 * techniques used in XFree86, but ours should be more reliable since we
 190 * attempt to make use of direct access hints provided by the PCI BIOS).
 191 *
 192 * This should be close to trivial, but it isn't, because there are buggy
 193 * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
 194 */
 195static int __init pci_sanity_check(const struct pci_raw_ops *o)
 196{
 197        u32 x = 0;
 198        int devfn;
 199
 200        if (pci_probe & PCI_NO_CHECKS)
 201                return 1;
 202        /* Assume Type 1 works for newer systems.
 203           This handles machines that don't have anything on PCI Bus 0. */
 204        if (dmi_get_bios_year() >= 2001)
 205                return 1;
 206
 207        for (devfn = 0; devfn < 0x100; devfn++) {
 208                if (o->read(0, 0, devfn, PCI_CLASS_DEVICE, 2, &x))
 209                        continue;
 210                if (x == PCI_CLASS_BRIDGE_HOST || x == PCI_CLASS_DISPLAY_VGA)
 211                        return 1;
 212
 213                if (o->read(0, 0, devfn, PCI_VENDOR_ID, 2, &x))
 214                        continue;
 215                if (x == PCI_VENDOR_ID_INTEL || x == PCI_VENDOR_ID_COMPAQ)
 216                        return 1;
 217        }
 218
 219        DBG(KERN_WARNING "PCI: Sanity check failed\n");
 220        return 0;
 221}
 222
 223static int __init pci_check_type1(void)
 224{
 225        unsigned long flags;
 226        unsigned int tmp;
 227        int works = 0;
 228
 229        local_irq_save(flags);
 230
 231        outb(0x01, 0xCFB);
 232        tmp = inl(0xCF8);
 233        outl(0x80000000, 0xCF8);
 234        if (inl(0xCF8) == 0x80000000 && pci_sanity_check(&pci_direct_conf1)) {
 235                works = 1;
 236        }
 237        outl(tmp, 0xCF8);
 238        local_irq_restore(flags);
 239
 240        return works;
 241}
 242
 243static int __init pci_check_type2(void)
 244{
 245        unsigned long flags;
 246        int works = 0;
 247
 248        local_irq_save(flags);
 249
 250        outb(0x00, 0xCFB);
 251        outb(0x00, 0xCF8);
 252        outb(0x00, 0xCFA);
 253        if (inb(0xCF8) == 0x00 && inb(0xCFA) == 0x00 &&
 254            pci_sanity_check(&pci_direct_conf2)) {
 255                works = 1;
 256        }
 257
 258        local_irq_restore(flags);
 259
 260        return works;
 261}
 262
 263void __init pci_direct_init(int type)
 264{
 265        if (type == 0)
 266                return;
 267        printk(KERN_INFO "PCI: Using configuration type %d for base access\n",
 268                 type);
 269        if (type == 1) {
 270                raw_pci_ops = &pci_direct_conf1;
 271                if (raw_pci_ext_ops)
 272                        return;
 273                if (!(pci_probe & PCI_HAS_IO_ECS))
 274                        return;
 275                printk(KERN_INFO "PCI: Using configuration type 1 "
 276                       "for extended access\n");
 277                raw_pci_ext_ops = &pci_direct_conf1;
 278                return;
 279        }
 280        raw_pci_ops = &pci_direct_conf2;
 281}
 282
 283int __init pci_direct_probe(void)
 284{
 285        if ((pci_probe & PCI_PROBE_CONF1) == 0)
 286                goto type2;
 287        if (!request_region(0xCF8, 8, "PCI conf1"))
 288                goto type2;
 289
 290        if (pci_check_type1()) {
 291                raw_pci_ops = &pci_direct_conf1;
 292                port_cf9_safe = true;
 293                return 1;
 294        }
 295        release_region(0xCF8, 8);
 296
 297 type2:
 298        if ((pci_probe & PCI_PROBE_CONF2) == 0)
 299                return 0;
 300        if (!request_region(0xCF8, 4, "PCI conf2"))
 301                return 0;
 302        if (!request_region(0xC000, 0x1000, "PCI conf2"))
 303                goto fail2;
 304
 305        if (pci_check_type2()) {
 306                raw_pci_ops = &pci_direct_conf2;
 307                port_cf9_safe = true;
 308                return 2;
 309        }
 310
 311        release_region(0xC000, 0x1000);
 312 fail2:
 313        release_region(0xCF8, 4);
 314        return 0;
 315}
 316