Consistency
[people/xl0/gpxe.git] / src / drivers / bus / pci.c
1 #include "etherboot.h"
2 #include "pci.h"
3
4 /*
5  * Ensure that there is sufficient space in the shared dev_bus
6  * structure for a struct pci_device.
7  *
8  */
9 DEV_BUS( struct pci_device, pci_dev );
10 static char pci_magic[0]; /* guaranteed unique symbol */
11
12 /*
13  * pci_io.c may know how many buses we have, in which case it can
14  * overwrite this value.
15  *
16  */
17 unsigned int pci_max_bus = 0xff;
18
19 /*
20  * Fill in parameters (vendor & device ids, class, membase etc.) for a
21  * PCI device based on bus & devfn.
22  *
23  * Returns 1 if a device was found, 0 for no device present.
24  */
25 static int fill_pci_device ( struct pci_device *pci ) {
26         static struct {
27                 uint16_t devfn0;
28                 int is_present;
29         } cache = { 0, 1 };
30         uint32_t l;
31         int reg;
32
33         /* Check bus is within range */
34         if ( PCI_BUS ( pci->busdevfn ) > pci_max_bus ) {
35                 return 0;
36         }
37
38         /* Check to see if we've cached the result that this is a
39          * non-zero function on a non-existent card.  This is done to
40          * increase scan speed by a factor of 8.
41          */
42         if ( ( PCI_FUNC ( pci->busdevfn ) != 0 ) &&
43              ( PCI_FN0 ( pci->busdevfn ) == cache.devfn0 ) &&
44              ( ! cache.is_present ) ) {
45                 return 0;
46         }
47         
48         /* Check to see if there's anything physically present.
49          */
50         pci_read_config_dword ( pci, PCI_VENDOR_ID, &l );
51         /* some broken boards return 0 if a slot is empty: */
52         if ( ( l == 0xffffffff ) || ( l == 0x00000000 ) ) {
53                 if ( PCI_FUNC ( pci->busdevfn ) == 0 ) {
54                         /* Don't look for subsequent functions if the
55                          * card itself is not present.
56                          */
57                         cache.devfn0 = pci->busdevfn;
58                         cache.is_present = 0;
59                 }
60                 return 0;
61         }
62         pci->vendor = l & 0xffff;
63         pci->dev_id = ( l >> 16 ) & 0xffff;
64         
65         /* Check that we're not a duplicate function on a
66          * non-multifunction device.
67          */
68         if ( PCI_FUNC ( pci->busdevfn ) != 0 ) {
69                 uint16_t save_busdevfn = pci->busdevfn;
70                 uint8_t header_type;
71
72                 pci->busdevfn &= PCI_FN0 ( pci->busdevfn );
73                 pci_read_config_byte ( pci, PCI_HEADER_TYPE, &header_type );
74                 pci->busdevfn = save_busdevfn;
75
76                 if ( ! ( header_type & 0x80 ) ) {
77                         return 0;
78                 }
79         }
80         
81         /* Get device class */
82         pci_read_config_word ( pci, PCI_SUBCLASS_CODE, &pci->class );
83
84         /* Get revision */
85         pci_read_config_byte ( pci, PCI_REVISION, &pci->revision );
86
87         /* Get the "membase" */
88         pci_read_config_dword ( pci, PCI_BASE_ADDRESS_1, &pci->membase );
89                                 
90         /* Get the "ioaddr" */
91         pci->ioaddr = 0;
92         for ( reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4 ) {
93                 pci_read_config_dword ( pci, reg, &pci->ioaddr );
94                 if ( pci->ioaddr & PCI_BASE_ADDRESS_SPACE_IO ) {
95                         pci->ioaddr &= PCI_BASE_ADDRESS_IO_MASK;
96                         if ( pci->ioaddr ) {
97                                 break;
98                         }
99                 }
100                 pci->ioaddr = 0;
101         }
102
103         /* Get the irq */
104         pci_read_config_byte ( pci, PCI_INTERRUPT_PIN, &pci->irq );
105         if ( pci->irq ) {
106                 pci_read_config_byte ( pci, PCI_INTERRUPT_LINE, &pci->irq );
107         }
108
109         DBG ( "PCI found device %hhx:%hhx.%d Class %hx: %hx:%hx (rev %hhx)\n",
110               PCI_BUS ( pci->busdevfn ), PCI_DEV ( pci->busdevfn ),
111               PCI_FUNC ( pci->busdevfn ), pci->class, pci->vendor, pci->dev_id,
112               pci->revision );
113
114         return 1;
115 }
116
117 /*
118  * Set device to be a busmaster in case BIOS neglected to do so.  Also
119  * adjust PCI latency timer to a reasonable value, 32.
120  */
121 void adjust_pci_device ( struct pci_device *pci ) {
122         unsigned short  new_command, pci_command;
123         unsigned char   pci_latency;
124
125         pci_read_config_word ( pci, PCI_COMMAND, &pci_command );
126         new_command = pci_command | PCI_COMMAND_MASTER | PCI_COMMAND_IO;
127         if ( pci_command != new_command ) {
128                 DBG ( "PCI BIOS has not enabled device %hhx:%hhx.%d! "
129                       "Updating PCI command %hX->%hX\n",
130                       PCI_BUS ( pci->busdevfn ), PCI_DEV ( pci->busdevfn ),
131                       PCI_FUNC ( pci->busdevfn ), pci_command, new_command );
132                 pci_write_config_word ( pci, PCI_COMMAND, new_command );
133         }
134         pci_read_config_byte ( pci, PCI_LATENCY_TIMER, &pci_latency);
135         if ( pci_latency < 32 ) {
136                 DBG ( "PCI device %hhx:%hhx.%d latency timer is "
137                       "unreasonably low at %d. Setting to 32.\n",
138                       PCI_BUS ( pci->busdevfn ), PCI_DEV ( pci->busdevfn ),
139                       PCI_FUNC ( pci->busdevfn ), pci_latency );
140                 pci_write_config_byte ( pci, PCI_LATENCY_TIMER, 32);
141         }
142 }
143
144 /*
145  * Set PCI device to use.
146  *
147  * This routine can be called by e.g. the ROM prefix to specify that
148  * the first device to be tried should be the device on which the ROM
149  * was physically located.
150  *
151  */
152 void set_pci_device ( uint16_t busdevfn ) {
153         pci_dev.magic = pci_magic;
154         pci_dev.busdevfn = busdevfn;
155         pci_dev.already_tried = 0;
156 }
157
158 /*
159  * Find a PCI device matching the specified driver
160  *
161  */
162 int find_pci_device ( struct pci_device *pci,
163                       struct pci_driver *driver ) {
164         int i;
165
166         /* Initialise struct pci if it's the first time it's been used. */
167         if ( pci->magic != pci_magic ) {
168                 memset ( pci, 0, sizeof ( *pci ) );
169                 pci->magic = pci_magic;
170         }
171
172         /* Iterate through all possible PCI bus:dev.fn combinations,
173          * starting where we left off.
174          */
175         DBG ( "PCI searching for device matching driver %s\n", driver->name );
176         do {
177                 /* If we've already used this device, skip it */
178                 if ( pci->already_tried ) {
179                         pci->already_tried = 0;
180                         continue;
181                 }
182                 
183                 /* Fill in device parameters, if device present */
184                 if ( ! fill_pci_device ( pci ) ) {
185                         continue;
186                 }
187                 
188                 /* Fix up PCI device */
189                 adjust_pci_device ( pci );
190                 
191                 /* If driver has a class, and class matches, use it */
192                 if ( driver->class && 
193                      ( driver->class == pci->class ) ) {
194                         DBG ( "PCI found class %hx matching driver %s\n",
195                               driver->class, driver->name );
196                         pci->name = driver->name;
197                         pci->already_tried = 1;
198                         return 1;
199                 }
200                 
201                 /* If any of driver's IDs match, use it */
202                 for ( i = 0 ; i < driver->id_count; i++ ) {
203                         struct pci_id *id = &driver->ids[i];
204                         
205                         if ( ( pci->vendor == id->vendor ) &&
206                              ( pci->dev_id == id->dev_id ) ) {
207                                 DBG ( "PCI found ID %hx:%hx (device %s) "
208                                       "matching driver %s\n", id->vendor,
209                                       id->dev_id, id->name, driver->name );
210                                 pci->name = id->name;
211                                 pci->already_tried = 1;
212                                 return 1;
213                         }
214                 }
215         } while ( ++pci->busdevfn );
216
217         /* No device found */
218         DBG ( "PCI found no device matching driver %s\n", driver->name );
219         return 0;
220 }
221
222 /*
223  * Find the next PCI device that can be used to boot using the
224  * specified driver.
225  *
226  */
227 int find_pci_boot_device ( struct dev *dev, struct pci_driver *driver ) {
228         struct pci_device *pci = ( struct pci_device * )dev->bus;
229
230         if ( ! find_pci_device ( pci, driver ) )
231                 return 0;
232
233         dev->name = pci->name;
234         dev->devid.bus_type = PCI_BUS_TYPE;
235         dev->devid.vendor_id = pci->vendor;
236         dev->devid.device_id = pci->dev_id;
237
238         return 1;
239 }
240
241 /*
242  * Find the start of a pci resource.
243  */
244 unsigned long pci_bar_start ( struct pci_device *pci, unsigned int index ) {
245         uint32_t lo, hi;
246         unsigned long bar;
247
248         pci_read_config_dword ( pci, index, &lo );
249         if ( lo & PCI_BASE_ADDRESS_SPACE_IO ) {
250                 bar = lo & PCI_BASE_ADDRESS_IO_MASK;
251         } else {
252                 bar = 0;
253                 if ( ( lo & PCI_BASE_ADDRESS_MEM_TYPE_MASK ) ==
254                      PCI_BASE_ADDRESS_MEM_TYPE_64) {
255                         pci_read_config_dword ( pci, index + 4, &hi );
256                         if ( hi ) {
257 #if ULONG_MAX > 0xffffffff
258                                         bar = hi;
259                                         bar <<= 32;
260 #else
261                                         printf ( "Unhandled 64bit BAR\n" );
262                                         return -1UL;
263 #endif
264                         }
265                 }
266                 bar |= lo & PCI_BASE_ADDRESS_MEM_MASK;
267         }
268         return bar + pci_bus_base ( pci );
269 }
270
271 /*
272  * Find the size of a pci resource.
273  */
274 unsigned long pci_bar_size ( struct pci_device *pci, unsigned int bar ) {
275         uint32_t start, size;
276
277         /* Save the original bar */
278         pci_read_config_dword ( pci, bar, &start );
279         /* Compute which bits can be set */
280         pci_write_config_dword ( pci, bar, ~0 );
281         pci_read_config_dword ( pci, bar, &size );
282         /* Restore the original size */
283         pci_write_config_dword ( pci, bar, start );
284         /* Find the significant bits */
285         if ( start & PCI_BASE_ADDRESS_SPACE_IO ) {
286                 size &= PCI_BASE_ADDRESS_IO_MASK;
287         } else {
288                 size &= PCI_BASE_ADDRESS_MEM_MASK;
289         }
290         /* Find the lowest bit set */
291         size = size & ~( size - 1 );
292         return size;
293 }
294
295 /**
296  * pci_find_capability - query for devices' capabilities 
297  * @pci: PCI device to query
298  * @cap: capability code
299  *
300  * Tell if a device supports a given PCI capability.
301  * Returns the address of the requested capability structure within the
302  * device's PCI configuration space or 0 in case the device does not
303  * support it.  Possible values for @cap:
304  *
305  *  %PCI_CAP_ID_PM           Power Management 
306  *
307  *  %PCI_CAP_ID_AGP          Accelerated Graphics Port 
308  *
309  *  %PCI_CAP_ID_VPD          Vital Product Data 
310  *
311  *  %PCI_CAP_ID_SLOTID       Slot Identification 
312  *
313  *  %PCI_CAP_ID_MSI          Message Signalled Interrupts
314  *
315  *  %PCI_CAP_ID_CHSWP        CompactPCI HotSwap 
316  */
317 int pci_find_capability ( struct pci_device *pci, int cap ) {
318         uint16_t status;
319         uint8_t pos, id;
320         uint8_t hdr_type;
321         int ttl = 48;
322
323         pci_read_config_word ( pci, PCI_STATUS, &status );
324         if ( ! ( status & PCI_STATUS_CAP_LIST ) )
325                 return 0;
326
327         pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdr_type );
328         switch ( hdr_type & 0x7F ) {
329         case PCI_HEADER_TYPE_NORMAL:
330         case PCI_HEADER_TYPE_BRIDGE:
331         default:
332                 pci_read_config_byte ( pci, PCI_CAPABILITY_LIST, &pos );
333                 break;
334         case PCI_HEADER_TYPE_CARDBUS:
335                 pci_read_config_byte ( pci, PCI_CB_CAPABILITY_LIST, &pos );
336                 break;
337         }
338         while ( ttl-- && pos >= 0x40 ) {
339                 pos &= ~3;
340                 pci_read_config_byte ( pci, pos + PCI_CAP_LIST_ID, &id );
341                 DBG ( "Capability: %d\n", id );
342                 if ( id == 0xff )
343                         break;
344                 if ( id == cap )
345                         return pos;
346                 pci_read_config_byte ( pci, pos + PCI_CAP_LIST_NEXT, &pos );
347         }
348         return 0;
349 }