3 * \brief Handling of PCI devices
6 * \author Frank Mehnert <fm3@os.inf.tu-dresden.de> */
8 * (c) 2002-2009 Technische Universität Dresden
9 * This file is part of TUD:OS and distributed under the terms of the
10 * GNU General Public License 2.
11 * Please see the COPYING-GPL-2 file for details.
15 #include <l4/re/c/namespace.h>
16 #include <l4/re/c/util/cap_alloc.h>
17 #include <l4/sys/err.h>
22 #define MAX_DRIVERS 16
26 const struct pci_device_id *dev;
27 int (*probe)(unsigned int bus, unsigned int devfn,
28 const struct pci_device_id *dev, con_accel_t *accel);
31 static struct pci_driver pci_drv[MAX_DRIVERS];
34 pci_register(const struct pci_device_id *tbl,
35 int(*probe)(unsigned int bus, unsigned int devfn,
36 const struct pci_device_id *dev, con_accel_t *accel))
38 struct pci_driver *drv;
40 for (drv = pci_drv; drv->dev; drv++)
42 if (drv >= pci_drv + MAX_DRIVERS-1)
44 printf("Too many drivers registered, increase MAX_DRIVERS!!\n");
53 l4_cap_idx_t vbus = L4_INVALID_CAP;
54 l4vbus_device_handle_t root_bridge = 0;
57 pci_probe(con_accel_t *accel)
62 vbus = l4re_get_env_cap("vbus");
63 if (l4_is_invalid_cap(vbus))
65 printf("PCI: query vbus service failed, no PCI\n");
69 err = l4vbus_get_device_by_hid(vbus, 0, &root_bridge, "PNP0A03", L4VBUS_MAX_DEPTH, 0);
72 printf("PCI: no root bridge found, no PCI\n");
77 unsigned slot, fn = 0;
78 /* only scan possible devices and subdevices on the first bus */
79 for (slot = 0; slot < 32; slot++)
80 //for (fn = 0; fn < 8; fn ++)
82 unsigned devfn = (slot << 16) | fn;
83 struct pci_driver *drv;
84 const struct pci_device_id *dev;
86 /* only scan for graphics cards */
87 unsigned class_id = 0;
88 PCIBIOS_READ_CONFIG_WORD(bus, devfn, PCI_CLASS_DEVICE, &class_id);
89 if (class_id != PCI_CLASS_DISPLAY_VGA)
91 printf("Found VGA device\n");
93 for (drv = pci_drv; drv->dev; drv++)
95 for (dev = drv->dev; dev->vendor; dev++)
97 unsigned vendor = 0, device = 0, sub_vendor = 0, sub_device = 0;
98 PCIBIOS_READ_CONFIG_WORD(bus, devfn, PCI_VENDOR_ID, &vendor);
99 PCIBIOS_READ_CONFIG_WORD(bus, devfn, PCI_DEVICE_ID, &device);
100 PCIBIOS_READ_CONFIG_WORD(bus, devfn, PCI_SUBSYSTEM_VENDOR_ID, &sub_vendor);
101 PCIBIOS_READ_CONFIG_WORD(bus, devfn, PCI_SUBSYSTEM_ID, &sub_device);
102 if (dev->vendor != vendor)
104 if (dev->device != 0)
105 if (dev->device != device)
108 if ((dev->svid != sub_vendor) ||
109 (dev->sid != sub_device))
112 /* found appropriate driver ... */
113 if ((ret = drv->probe(bus, devfn, dev, accel)) != 0)
126 pci_resource(unsigned int bus, unsigned int devfn,
127 int num, l4_addr_t *addr, l4_size_t *size)
133 case 0: reg = PCI_BASE_ADDRESS_0; break;
134 case 1: reg = PCI_BASE_ADDRESS_1; break;
135 case 2: reg = PCI_BASE_ADDRESS_2; break;
139 PCIBIOS_READ_CONFIG_DWORD (bus, devfn, reg, &l);
140 PCIBIOS_WRITE_CONFIG_DWORD(bus, devfn, reg, ~0);
141 PCIBIOS_READ_CONFIG_DWORD (bus, devfn, reg, &sz);
142 PCIBIOS_WRITE_CONFIG_DWORD(bus, devfn, reg, l);
143 if ((l & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY)
145 *addr = l & PCI_BASE_ADDRESS_MEM_MASK;
146 sz &= PCI_BASE_ADDRESS_MEM_MASK;
147 *size = sz & ~(sz - 1);
151 *addr = l & PCI_BASE_ADDRESS_IO_MASK;
152 sz &= PCI_BASE_ADDRESS_IO_MASK & 0xffff;
153 *size = sz & ~(sz - 1);