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., 675 Mass Ave, Cambridge, MA 02139, USA.
22 FILE_LICENCE ( GPL2_OR_LATER
);
29 #include <gpxe/tables.h>
30 #include <gpxe/device.h>
39 static void pcibus_remove ( struct root_device
*rootdev
);
45 * @v reg PCI register number
46 * @ret bar Base address register
48 * Reads the specified PCI base address register, including the flags
49 * portion. 64-bit BARs will be handled automatically. If the value
50 * of the 64-bit BAR exceeds the size of an unsigned long (i.e. if the
51 * high dword is non-zero on a 32-bit platform), then the value
52 * returned will be zero plus the flags for a 64-bit BAR. Unreachable
53 * 64-bit BARs are therefore returned as uninitialised 64-bit BARs.
55 static unsigned long pci_bar ( struct pci_device
*pci
, unsigned int reg
) {
59 pci_read_config_dword ( pci
, reg
, &low
);
60 if ( ( low
& (PCI_BASE_ADDRESS_SPACE
|PCI_BASE_ADDRESS_MEM_TYPE_MASK
) )
61 == (PCI_BASE_ADDRESS_SPACE_MEMORY
|PCI_BASE_ADDRESS_MEM_TYPE_64
) ){
62 pci_read_config_dword ( pci
, reg
+ 4, &high
);
64 if ( sizeof ( unsigned long ) > sizeof ( uint32_t ) ) {
65 return ( ( ( uint64_t ) high
<< 32 ) | low
);
67 DBG ( "Unhandled 64-bit BAR %08x%08x\n",
69 return PCI_BASE_ADDRESS_MEM_TYPE_64
;
77 * Find the start of a PCI BAR
80 * @v reg PCI register number
81 * @ret start BAR start address
83 * Reads the specified PCI base address register, and returns the
84 * address portion of the BAR (i.e. without the flags).
86 * If the address exceeds the size of an unsigned long (i.e. if a
87 * 64-bit BAR has a non-zero high dword on a 32-bit machine), the
88 * return value will be zero.
90 unsigned long pci_bar_start ( struct pci_device
*pci
, unsigned int reg
) {
93 bar
= pci_bar ( pci
, reg
);
94 if ( (bar
& PCI_BASE_ADDRESS_SPACE
) == PCI_BASE_ADDRESS_SPACE_MEMORY
){
95 return ( bar
& PCI_BASE_ADDRESS_MEM_MASK
);
97 return ( bar
& PCI_BASE_ADDRESS_IO_MASK
);
102 * Read membase and ioaddr for a PCI device
106 * This scans through all PCI BARs on the specified device. The first
107 * valid memory BAR is recorded as pci_device::membase, and the first
108 * valid IO BAR is recorded as pci_device::ioaddr.
110 * 64-bit BARs are handled automatically. On a 32-bit platform, if a
111 * 64-bit BAR has a non-zero high dword, it will be regarded as
114 static void pci_read_bases ( struct pci_device
*pci
) {
118 for ( reg
= PCI_BASE_ADDRESS_0
; reg
<= PCI_BASE_ADDRESS_5
; reg
+= 4 ) {
119 bar
= pci_bar ( pci
, reg
);
120 if ( bar
& PCI_BASE_ADDRESS_SPACE_IO
) {
123 ( bar
& PCI_BASE_ADDRESS_IO_MASK
);
125 if ( ! pci
->membase
)
127 ( bar
& PCI_BASE_ADDRESS_MEM_MASK
);
128 /* Skip next BAR if 64-bit */
129 if ( bar
& PCI_BASE_ADDRESS_MEM_TYPE_64
)
140 * Set device to be a busmaster in case BIOS neglected to do so. Also
141 * adjust PCI latency timer to a reasonable value, 32.
143 void adjust_pci_device ( struct pci_device
*pci
) {
144 unsigned short new_command
, pci_command
;
145 unsigned char pci_latency
;
147 pci_read_config_word ( pci
, PCI_COMMAND
, &pci_command
);
148 new_command
= ( pci_command
| PCI_COMMAND_MASTER
|
149 PCI_COMMAND_MEM
| PCI_COMMAND_IO
);
150 if ( pci_command
!= new_command
) {
151 DBG ( "PCI BIOS has not enabled device %02x:%02x.%x! "
152 "Updating PCI command %04x->%04x\n", pci
->bus
,
153 PCI_SLOT ( pci
->devfn
), PCI_FUNC ( pci
->devfn
),
154 pci_command
, new_command
);
155 pci_write_config_word ( pci
, PCI_COMMAND
, new_command
);
158 pci_read_config_byte ( pci
, PCI_LATENCY_TIMER
, &pci_latency
);
159 if ( pci_latency
< 32 ) {
160 DBG ( "PCI device %02x:%02x.%x latency timer is unreasonably "
161 "low at %d. Setting to 32.\n", pci
->bus
,
162 PCI_SLOT ( pci
->devfn
), PCI_FUNC ( pci
->devfn
),
164 pci_write_config_byte ( pci
, PCI_LATENCY_TIMER
, 32);
172 * @ret rc Return status code
174 * Searches for a driver for the PCI device. If a driver is found,
175 * its probe() routine is called.
177 static int pci_probe ( struct pci_device
*pci
) {
178 struct pci_driver
*driver
;
179 struct pci_device_id
*id
;
183 DBG ( "Adding PCI device %02x:%02x.%x (%04x:%04x mem %lx io %lx "
184 "irq %d)\n", pci
->bus
, PCI_SLOT ( pci
->devfn
),
185 PCI_FUNC ( pci
->devfn
), pci
->vendor
, pci
->device
,
186 pci
->membase
, pci
->ioaddr
, pci
->irq
);
188 for_each_table_entry ( driver
, PCI_DRIVERS
) {
189 for ( i
= 0 ; i
< driver
->id_count
; i
++ ) {
190 id
= &driver
->ids
[i
];
191 if ( ( id
->vendor
!= PCI_ANY_ID
) &&
192 ( id
->vendor
!= pci
->vendor
) )
194 if ( ( id
->device
!= PCI_ANY_ID
) &&
195 ( id
->device
!= pci
->device
) )
197 pci
->driver
= driver
;
198 pci
->driver_name
= id
->name
;
199 DBG ( "...using driver %s\n", pci
->driver_name
);
200 if ( ( rc
= driver
->probe ( pci
, id
) ) != 0 ) {
201 DBG ( "......probe failed\n" );
208 DBG ( "...no driver found\n" );
213 * Remove a PCI device
217 static void pci_remove ( struct pci_device
*pci
) {
218 pci
->driver
->remove ( pci
);
219 DBG ( "Removed PCI device %02x:%02x.%x\n", pci
->bus
,
220 PCI_SLOT ( pci
->devfn
), PCI_FUNC ( pci
->devfn
) );
226 * @v rootdev PCI bus root device
228 * Scans the PCI bus for devices and registers all devices it can
231 static int pcibus_probe ( struct root_device
*rootdev
) {
232 struct pci_device
*pci
= NULL
;
233 unsigned int max_bus
;
240 max_bus
= pci_max_bus();
241 for ( bus
= 0 ; bus
<= max_bus
; bus
++ ) {
242 for ( devfn
= 0 ; devfn
<= 0xff ; devfn
++ ) {
244 /* Allocate struct pci_device */
246 pci
= malloc ( sizeof ( *pci
) );
251 memset ( pci
, 0, sizeof ( *pci
) );
255 /* Skip all but the first function on
256 * non-multifunction cards
258 if ( PCI_FUNC ( devfn
) == 0 ) {
259 pci_read_config_byte ( pci
, PCI_HEADER_TYPE
,
261 } else if ( ! ( hdrtype
& 0x80 ) ) {
265 /* Check for physical device presence */
266 pci_read_config_dword ( pci
, PCI_VENDOR_ID
, &tmp
);
267 if ( ( tmp
== 0xffffffff ) || ( tmp
== 0 ) )
270 /* Populate struct pci_device */
271 pci
->vendor
= ( tmp
& 0xffff );
272 pci
->device
= ( tmp
>> 16 );
273 pci_read_config_dword ( pci
, PCI_REVISION
, &tmp
);
274 pci
->class = ( tmp
>> 8 );
275 pci_read_config_byte ( pci
, PCI_INTERRUPT_LINE
,
277 pci_read_bases ( pci
);
279 /* Add to device hierarchy */
280 snprintf ( pci
->dev
.name
, sizeof ( pci
->dev
.name
),
281 "PCI%02x:%02x.%x", bus
,
282 PCI_SLOT ( devfn
), PCI_FUNC ( devfn
) );
283 pci
->dev
.desc
.bus_type
= BUS_TYPE_PCI
;
284 pci
->dev
.desc
.location
= PCI_BUSDEVFN (bus
, devfn
);
285 pci
->dev
.desc
.vendor
= pci
->vendor
;
286 pci
->dev
.desc
.device
= pci
->device
;
287 pci
->dev
.desc
.class = pci
->class;
288 pci
->dev
.desc
.ioaddr
= pci
->ioaddr
;
289 pci
->dev
.desc
.irq
= pci
->irq
;
290 pci
->dev
.parent
= &rootdev
->dev
;
291 list_add ( &pci
->dev
.siblings
, &rootdev
->dev
.children
);
292 INIT_LIST_HEAD ( &pci
->dev
.children
);
294 /* Look for a driver */
295 if ( pci_probe ( pci
) == 0 ) {
296 /* pcidev registered, we can drop our ref */
299 /* Not registered; re-use struct pci_device */
300 list_del ( &pci
->dev
.siblings
);
310 pcibus_remove ( rootdev
);
315 * Remove PCI root bus
317 * @v rootdev PCI bus root device
319 static void pcibus_remove ( struct root_device
*rootdev
) {
320 struct pci_device
*pci
;
321 struct pci_device
*tmp
;
323 list_for_each_entry_safe ( pci
, tmp
, &rootdev
->dev
.children
,
326 list_del ( &pci
->dev
.siblings
);
331 /** PCI bus root device driver */
332 static struct root_driver pci_root_driver
= {
333 .probe
= pcibus_probe
,
334 .remove
= pcibus_remove
,
337 /** PCI bus root device */
338 struct root_device pci_root_device __root_device
= {
339 .dev
= { .name
= "PCI" },
340 .driver
= &pci_root_driver
,