2 * Copyright (C) 2006 Michael Brown <mbrown@fensystems.co.uk>.
4 * Based in part on pci.c from Etherboot 5.4, by Ken Yap and David
5 * Munro, in turn based on the Linux kernel's PCI implementation.
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or any later version.
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22 * You can also choose to distribute this program under the terms of
23 * the Unmodified Binary Distribution Licence (as given in the file
24 * COPYING.UBDL), provided that you have satisfied its requirements.
27 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL
);
34 #include <ipxe/tables.h>
35 #include <ipxe/device.h>
44 static void pcibus_remove ( struct root_device
*rootdev
);
50 * @v reg PCI register number
51 * @ret bar Base address register
53 * Reads the specified PCI base address register, including the flags
54 * portion. 64-bit BARs will be handled automatically. If the value
55 * of the 64-bit BAR exceeds the size of an unsigned long (i.e. if the
56 * high dword is non-zero on a 32-bit platform), then the value
57 * returned will be zero plus the flags for a 64-bit BAR. Unreachable
58 * 64-bit BARs are therefore returned as uninitialised 64-bit BARs.
60 static unsigned long pci_bar ( struct pci_device
*pci
, unsigned int reg
) {
64 pci_read_config_dword ( pci
, reg
, &low
);
65 if ( ( low
& (PCI_BASE_ADDRESS_SPACE_IO
|PCI_BASE_ADDRESS_MEM_TYPE_MASK
))
66 == PCI_BASE_ADDRESS_MEM_TYPE_64
) {
67 pci_read_config_dword ( pci
, reg
+ 4, &high
);
69 if ( sizeof ( unsigned long ) > sizeof ( uint32_t ) ) {
70 return ( ( ( uint64_t ) high
<< 32 ) | low
);
72 DBGC ( pci
, PCI_FMT
" unhandled 64-bit BAR "
74 PCI_ARGS ( pci
), high
, low
);
75 return PCI_BASE_ADDRESS_MEM_TYPE_64
;
83 * Find the start of a PCI BAR
86 * @v reg PCI register number
87 * @ret start BAR start address
89 * Reads the specified PCI base address register, and returns the
90 * address portion of the BAR (i.e. without the flags).
92 * If the address exceeds the size of an unsigned long (i.e. if a
93 * 64-bit BAR has a non-zero high dword on a 32-bit machine), the
94 * return value will be zero.
96 unsigned long pci_bar_start ( struct pci_device
*pci
, unsigned int reg
) {
99 bar
= pci_bar ( pci
, reg
);
100 if ( bar
& PCI_BASE_ADDRESS_SPACE_IO
) {
101 return ( bar
& ~PCI_BASE_ADDRESS_IO_MASK
);
103 return ( bar
& ~PCI_BASE_ADDRESS_MEM_MASK
);
108 * Read membase and ioaddr for a PCI device
112 * This scans through all PCI BARs on the specified device. The first
113 * valid memory BAR is recorded as pci_device::membase, and the first
114 * valid IO BAR is recorded as pci_device::ioaddr.
116 * 64-bit BARs are handled automatically. On a 32-bit platform, if a
117 * 64-bit BAR has a non-zero high dword, it will be regarded as
120 static void pci_read_bases ( struct pci_device
*pci
) {
124 for ( reg
= PCI_BASE_ADDRESS_0
; reg
<= PCI_BASE_ADDRESS_5
; reg
+= 4 ) {
125 bar
= pci_bar ( pci
, reg
);
126 if ( bar
& PCI_BASE_ADDRESS_SPACE_IO
) {
129 ( bar
& ~PCI_BASE_ADDRESS_IO_MASK
);
131 if ( ! pci
->membase
)
133 ( bar
& ~PCI_BASE_ADDRESS_MEM_MASK
);
134 /* Skip next BAR if 64-bit */
135 if ( bar
& PCI_BASE_ADDRESS_MEM_TYPE_64
)
146 * Set device to be a busmaster in case BIOS neglected to do so. Also
147 * adjust PCI latency timer to a reasonable value, 32.
149 void adjust_pci_device ( struct pci_device
*pci
) {
150 unsigned short new_command
, pci_command
;
151 unsigned char pci_latency
;
153 pci_read_config_word ( pci
, PCI_COMMAND
, &pci_command
);
154 new_command
= ( pci_command
| PCI_COMMAND_MASTER
|
155 PCI_COMMAND_MEM
| PCI_COMMAND_IO
);
156 if ( pci_command
!= new_command
) {
157 DBGC ( pci
, PCI_FMT
" device not enabled by BIOS! Updating "
158 "PCI command %04x->%04x\n",
159 PCI_ARGS ( pci
), pci_command
, new_command
);
160 pci_write_config_word ( pci
, PCI_COMMAND
, new_command
);
163 pci_read_config_byte ( pci
, PCI_LATENCY_TIMER
, &pci_latency
);
164 if ( pci_latency
< 32 ) {
165 DBGC ( pci
, PCI_FMT
" latency timer is unreasonably low at "
166 "%d. Setting to 32.\n", PCI_ARGS ( pci
), pci_latency
);
167 pci_write_config_byte ( pci
, PCI_LATENCY_TIMER
, 32);
172 * Read PCI device configuration
175 * @ret rc Return status code
177 int pci_read_config ( struct pci_device
*pci
) {
182 /* Ignore all but the first function on non-multifunction devices */
183 if ( PCI_FUNC ( pci
->busdevfn
) != 0 ) {
184 busdevfn
= pci
->busdevfn
;
185 pci
->busdevfn
= PCI_FIRST_FUNC ( pci
->busdevfn
);
186 pci_read_config_byte ( pci
, PCI_HEADER_TYPE
, &hdrtype
);
187 pci
->busdevfn
= busdevfn
;
188 if ( ! ( hdrtype
& PCI_HEADER_TYPE_MULTI
) )
192 /* Check for physical device presence */
193 pci_read_config_dword ( pci
, PCI_VENDOR_ID
, &tmp
);
194 if ( ( tmp
== 0xffffffff ) || ( tmp
== 0 ) )
197 /* Populate struct pci_device */
198 pci
->vendor
= ( tmp
& 0xffff );
199 pci
->device
= ( tmp
>> 16 );
200 pci_read_config_dword ( pci
, PCI_REVISION
, &tmp
);
201 pci
->class = ( tmp
>> 8 );
202 pci_read_config_byte ( pci
, PCI_INTERRUPT_LINE
, &pci
->irq
);
203 pci_read_bases ( pci
);
205 /* Initialise generic device component */
206 snprintf ( pci
->dev
.name
, sizeof ( pci
->dev
.name
),
207 "PCI%02x:%02x.%x", PCI_BUS ( pci
->busdevfn
),
208 PCI_SLOT ( pci
->busdevfn
), PCI_FUNC ( pci
->busdevfn
) );
209 pci
->dev
.desc
.bus_type
= BUS_TYPE_PCI
;
210 pci
->dev
.desc
.location
= pci
->busdevfn
;
211 pci
->dev
.desc
.vendor
= pci
->vendor
;
212 pci
->dev
.desc
.device
= pci
->device
;
213 pci
->dev
.desc
.class = pci
->class;
214 pci
->dev
.desc
.ioaddr
= pci
->ioaddr
;
215 pci
->dev
.desc
.irq
= pci
->irq
;
216 INIT_LIST_HEAD ( &pci
->dev
.siblings
);
217 INIT_LIST_HEAD ( &pci
->dev
.children
);
223 * Find next device on PCI bus
225 * @v pci PCI device to fill in
226 * @v busdevfn Starting bus:dev.fn address
227 * @ret busdevfn Bus:dev.fn address of next PCI device, or negative error
229 int pci_find_next ( struct pci_device
*pci
, unsigned int busdevfn
) {
230 static unsigned int end
;
233 /* Determine number of PCI buses */
235 end
= PCI_BUSDEVFN ( pci_num_bus(), 0, 0 );
237 /* Find next PCI device, if any */
238 for ( ; busdevfn
< end
; busdevfn
++ ) {
239 memset ( pci
, 0, sizeof ( *pci
) );
240 pci_init ( pci
, busdevfn
);
241 if ( ( rc
= pci_read_config ( pci
) ) == 0 )
249 * Find driver for PCI device
252 * @ret rc Return status code
254 int pci_find_driver ( struct pci_device
*pci
) {
255 struct pci_driver
*driver
;
256 struct pci_device_id
*id
;
259 for_each_table_entry ( driver
, PCI_DRIVERS
) {
260 if ( ( driver
->class.class ^ pci
->class ) & driver
->class.mask
)
262 for ( i
= 0 ; i
< driver
->id_count
; i
++ ) {
263 id
= &driver
->ids
[i
];
264 if ( ( id
->vendor
!= PCI_ANY_ID
) &&
265 ( id
->vendor
!= pci
->vendor
) )
267 if ( ( id
->device
!= PCI_ANY_ID
) &&
268 ( id
->device
!= pci
->device
) )
270 pci_set_driver ( pci
, driver
, id
);
281 * @ret rc Return status code
283 * Searches for a driver for the PCI device. If a driver is found,
284 * its probe() routine is called.
286 int pci_probe ( struct pci_device
*pci
) {
289 DBGC ( pci
, PCI_FMT
" (%04x:%04x) has driver \"%s\"\n",
290 PCI_ARGS ( pci
), pci
->vendor
, pci
->device
, pci
->id
->name
);
291 DBGC ( pci
, PCI_FMT
" has mem %lx io %lx irq %d\n",
292 PCI_ARGS ( pci
), pci
->membase
, pci
->ioaddr
, pci
->irq
);
294 if ( ( rc
= pci
->driver
->probe ( pci
) ) != 0 ) {
295 DBGC ( pci
, PCI_FMT
" probe failed: %s\n",
296 PCI_ARGS ( pci
), strerror ( rc
) );
304 * Remove a PCI device
308 void pci_remove ( struct pci_device
*pci
) {
309 pci
->driver
->remove ( pci
);
310 DBGC ( pci
, PCI_FMT
" removed\n", PCI_ARGS ( pci
) );
316 * @v rootdev PCI bus root device
318 * Scans the PCI bus for devices and registers all devices it can
321 static int pcibus_probe ( struct root_device
*rootdev
) {
322 struct pci_device
*pci
= NULL
;
326 for ( busdevfn
= 0 ; 1 ; busdevfn
++ ) {
328 /* Allocate struct pci_device */
330 pci
= malloc ( sizeof ( *pci
) );
336 /* Find next PCI device, if any */
337 busdevfn
= pci_find_next ( pci
, busdevfn
);
341 /* Look for a driver */
342 if ( ( rc
= pci_find_driver ( pci
) ) != 0 ) {
343 DBGC ( pci
, PCI_FMT
" (%04x:%04x class %06x) has no "
344 "driver\n", PCI_ARGS ( pci
), pci
->vendor
,
345 pci
->device
, pci
->class );
349 /* Add to device hierarchy */
350 pci
->dev
.parent
= &rootdev
->dev
;
351 list_add ( &pci
->dev
.siblings
, &rootdev
->dev
.children
);
353 /* Look for a driver */
354 if ( ( rc
= pci_probe ( pci
) ) == 0 ) {
355 /* pcidev registered, we can drop our ref */
358 /* Not registered; re-use struct pci_device */
359 list_del ( &pci
->dev
.siblings
);
368 pcibus_remove ( rootdev
);
373 * Remove PCI root bus
375 * @v rootdev PCI bus root device
377 static void pcibus_remove ( struct root_device
*rootdev
) {
378 struct pci_device
*pci
;
379 struct pci_device
*tmp
;
381 list_for_each_entry_safe ( pci
, tmp
, &rootdev
->dev
.children
,
384 list_del ( &pci
->dev
.siblings
);
389 /** PCI bus root device driver */
390 static struct root_driver pci_root_driver
= {
391 .probe
= pcibus_probe
,
392 .remove
= pcibus_remove
,
395 /** PCI bus root device */
396 struct root_device pci_root_device __root_device
= {
397 .dev
= { .name
= "PCI" },
398 .driver
= &pci_root_driver
,