1 #include <console/console.h>
2 #include <arch/pciconf.h>
3 #include <device/pci.h>
4 #include <device/pci_ids.h>
5 #include <device/pci_ops.h>
7 static const struct pci_ops *conf;
9 uint8_t (*read8) (uint8_t bus, int devfn, int where);
10 uint16_t (*read16) (uint8_t bus, int devfn, int where);
11 uint32_t (*read32) (uint8_t bus, int devfn, int where);
12 int (*write8) (uint8_t bus, int devfn, int where, uint8_t val);
13 int (*write16) (uint8_t bus, int devfn, int where, uint16_t val);
14 int (*write32) (uint8_t bus, int devfn, int where, uint32_t val);
17 struct pci_ops pci_direct_ppc;
20 * Before we decide to use direct hardware access mechanisms, we try to do some
21 * trivial checks to ensure it at least _seems_ to be working -- we just test
22 * whether bus 00 contains a host bridge (this is similar to checking
23 * techniques used in XFree86, but ours should be more reliable since we
24 * attempt to make use of direct access hints provided by the PCI BIOS).
26 * This should be close to trivial, but it isn't, because there are buggy
27 * chipsets (yes, you guessed it, by Intel and Compaq) that have no class ID.
29 static int pci_sanity_check(const struct pci_ops *o)
31 uint16_t class, vendor;
34 #define PCI_CLASS_BRIDGE_HOST 0x0600
35 #define PCI_CLASS_DISPLAY_VGA 0x0300
36 #define PCI_VENDOR_ID_COMPAQ 0x0e11
37 #define PCI_VENDOR_ID_INTEL 0x8086
38 #define PCI_VENDOR_ID_MOTOROLA 0x1057
39 #define PCI_VENDOR_ID_IBM 0x1014
41 for (bus = 0, devfn = 0; devfn < 0x100; devfn++) {
42 class = o->read16(bus, devfn, PCI_CLASS_DEVICE);
43 vendor = o->read16(bus, devfn, PCI_VENDOR_ID);
44 if (((class == PCI_CLASS_BRIDGE_HOST) ||
45 (class == PCI_CLASS_DISPLAY_VGA)) ||
46 ((vendor == PCI_VENDOR_ID_INTEL) ||
47 (vendor == PCI_VENDOR_ID_COMPAQ) ||
48 (vendor == PCI_VENDOR_ID_MOTOROLA) ||
49 (vendor == PCI_VENDOR_ID_IBM))) {
54 printk_err("PCI: Sanity check failed\n");
58 uint8_t pci_read_config8(device_t dev, unsigned where)
60 return conf->read8(dev->bus->secondary, dev->path.u.pci.devfn, where);
63 uint16_t pci_read_config16(struct device *dev, unsigned where)
65 return conf->read16(dev->bus->secondary, dev->path.u.pci.devfn, where);
68 uint32_t pci_read_config32(struct device *dev, unsigned where)
70 return conf->read32(dev->bus->secondary, dev->path.u.pci.devfn, where);
73 void pci_write_config8(struct device *dev, unsigned where, uint8_t val)
75 conf->write8(dev->bus->secondary, dev->path.u.pci.devfn, where, val);
78 void pci_write_config16(struct device *dev, unsigned where, uint16_t val)
80 conf->write16(dev->bus->secondary, dev->path.u.pci.devfn, where, val);
83 void pci_write_config32(struct device *dev, unsigned where, uint32_t val)
85 conf->write32(dev->bus->secondary, dev->path.u.pci.devfn, where, val);
88 /** Set the method to be used for PCI
90 void pci_set_method(void)
92 conf = &pci_direct_ppc;
93 pci_sanity_check(conf);
96 struct pci_ops pci_direct_ppc =
99 pci_ppc_read_config16,
100 pci_ppc_read_config32,
101 pci_ppc_write_config8,
102 pci_ppc_write_config16,
103 pci_ppc_write_config32