00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 FILE_LICENCE ( GPL2_OR_LATER );
00023
00024 #include <stdint.h>
00025 #include <stdlib.h>
00026 #include <stdio.h>
00027 #include <string.h>
00028 #include <errno.h>
00029 #include <gpxe/tables.h>
00030 #include <gpxe/device.h>
00031 #include <gpxe/pci.h>
00032
00033
00034
00035
00036
00037
00038
00039 static void pcibus_remove ( struct root_device *rootdev );
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 static unsigned long pci_bar ( struct pci_device *pci, unsigned int reg ) {
00056 uint32_t low;
00057 uint32_t high;
00058
00059 pci_read_config_dword ( pci, reg, &low );
00060 if ( ( low & (PCI_BASE_ADDRESS_SPACE|PCI_BASE_ADDRESS_MEM_TYPE_MASK) )
00061 == (PCI_BASE_ADDRESS_SPACE_MEMORY|PCI_BASE_ADDRESS_MEM_TYPE_64) ){
00062 pci_read_config_dword ( pci, reg + 4, &high );
00063 if ( high ) {
00064 if ( sizeof ( unsigned long ) > sizeof ( uint32_t ) ) {
00065 return ( ( ( uint64_t ) high << 32 ) | low );
00066 } else {
00067 DBG ( "Unhandled 64-bit BAR %08x%08x\n",
00068 high, low );
00069 return PCI_BASE_ADDRESS_MEM_TYPE_64;
00070 }
00071 }
00072 }
00073 return low;
00074 }
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090 unsigned long pci_bar_start ( struct pci_device *pci, unsigned int reg ) {
00091 unsigned long bar;
00092
00093 bar = pci_bar ( pci, reg );
00094 if ( (bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY ){
00095 return ( bar & PCI_BASE_ADDRESS_MEM_MASK );
00096 } else {
00097 return ( bar & PCI_BASE_ADDRESS_IO_MASK );
00098 }
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 static void pci_read_bases ( struct pci_device *pci ) {
00115 unsigned long bar;
00116 int reg;
00117
00118 for ( reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4 ) {
00119 bar = pci_bar ( pci, reg );
00120 if ( bar & PCI_BASE_ADDRESS_SPACE_IO ) {
00121 if ( ! pci->ioaddr )
00122 pci->ioaddr =
00123 ( bar & PCI_BASE_ADDRESS_IO_MASK );
00124 } else {
00125 if ( ! pci->membase )
00126 pci->membase =
00127 ( bar & PCI_BASE_ADDRESS_MEM_MASK );
00128
00129 if ( bar & PCI_BASE_ADDRESS_MEM_TYPE_64 )
00130 reg += 4;
00131 }
00132 }
00133 }
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143 void adjust_pci_device ( struct pci_device *pci ) {
00144 unsigned short new_command, pci_command;
00145 unsigned char pci_latency;
00146
00147 pci_read_config_word ( pci, PCI_COMMAND, &pci_command );
00148 new_command = ( pci_command | PCI_COMMAND_MASTER |
00149 PCI_COMMAND_MEM | PCI_COMMAND_IO );
00150 if ( pci_command != new_command ) {
00151 DBG ( "PCI BIOS has not enabled device %02x:%02x.%x! "
00152 "Updating PCI command %04x->%04x\n", pci->bus,
00153 PCI_SLOT ( pci->devfn ), PCI_FUNC ( pci->devfn ),
00154 pci_command, new_command );
00155 pci_write_config_word ( pci, PCI_COMMAND, new_command );
00156 }
00157
00158 pci_read_config_byte ( pci, PCI_LATENCY_TIMER, &pci_latency);
00159 if ( pci_latency < 32 ) {
00160 DBG ( "PCI device %02x:%02x.%x latency timer is unreasonably "
00161 "low at %d. Setting to 32.\n", pci->bus,
00162 PCI_SLOT ( pci->devfn ), PCI_FUNC ( pci->devfn ),
00163 pci_latency );
00164 pci_write_config_byte ( pci, PCI_LATENCY_TIMER, 32);
00165 }
00166 }
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177 static int pci_probe ( struct pci_device *pci ) {
00178 struct pci_driver *driver;
00179 struct pci_device_id *id;
00180 unsigned int i;
00181 int rc;
00182
00183 DBG ( "Adding PCI device %02x:%02x.%x (%04x:%04x mem %lx io %lx "
00184 "irq %d)\n", pci->bus, PCI_SLOT ( pci->devfn ),
00185 PCI_FUNC ( pci->devfn ), pci->vendor, pci->device,
00186 pci->membase, pci->ioaddr, pci->irq );
00187
00188 for_each_table_entry ( driver, PCI_DRIVERS ) {
00189 for ( i = 0 ; i < driver->id_count ; i++ ) {
00190 id = &driver->ids[i];
00191 if ( ( id->vendor != PCI_ANY_ID ) &&
00192 ( id->vendor != pci->vendor ) )
00193 continue;
00194 if ( ( id->device != PCI_ANY_ID ) &&
00195 ( id->device != pci->device ) )
00196 continue;
00197 pci->driver = driver;
00198 pci->driver_name = id->name;
00199 DBG ( "...using driver %s\n", pci->driver_name );
00200 if ( ( rc = driver->probe ( pci, id ) ) != 0 ) {
00201 DBG ( "......probe failed\n" );
00202 continue;
00203 }
00204 return 0;
00205 }
00206 }
00207
00208 DBG ( "...no driver found\n" );
00209 return -ENOTTY;
00210 }
00211
00212
00213
00214
00215
00216
00217 static void pci_remove ( struct pci_device *pci ) {
00218 pci->driver->remove ( pci );
00219 DBG ( "Removed PCI device %02x:%02x.%x\n", pci->bus,
00220 PCI_SLOT ( pci->devfn ), PCI_FUNC ( pci->devfn ) );
00221 }
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 static int pcibus_probe ( struct root_device *rootdev ) {
00232 struct pci_device *pci = NULL;
00233 unsigned int max_bus;
00234 unsigned int bus;
00235 unsigned int devfn;
00236 uint8_t hdrtype = 0;
00237 uint32_t tmp;
00238 int rc;
00239
00240 max_bus = pci_max_bus();
00241 for ( bus = 0 ; bus <= max_bus ; bus++ ) {
00242 for ( devfn = 0 ; devfn <= 0xff ; devfn++ ) {
00243
00244
00245 if ( ! pci )
00246 pci = malloc ( sizeof ( *pci ) );
00247 if ( ! pci ) {
00248 rc = -ENOMEM;
00249 goto err;
00250 }
00251 memset ( pci, 0, sizeof ( *pci ) );
00252 pci->bus = bus;
00253 pci->devfn = devfn;
00254
00255
00256
00257
00258 if ( PCI_FUNC ( devfn ) == 0 ) {
00259 pci_read_config_byte ( pci, PCI_HEADER_TYPE,
00260 &hdrtype );
00261 } else if ( ! ( hdrtype & 0x80 ) ) {
00262 continue;
00263 }
00264
00265
00266 pci_read_config_dword ( pci, PCI_VENDOR_ID, &tmp );
00267 if ( ( tmp == 0xffffffff ) || ( tmp == 0 ) )
00268 continue;
00269
00270
00271 pci->vendor = ( tmp & 0xffff );
00272 pci->device = ( tmp >> 16 );
00273 pci_read_config_dword ( pci, PCI_REVISION, &tmp );
00274 pci->class = ( tmp >> 8 );
00275 pci_read_config_byte ( pci, PCI_INTERRUPT_LINE,
00276 &pci->irq );
00277 pci_read_bases ( pci );
00278
00279
00280 snprintf ( pci->dev.name, sizeof ( pci->dev.name ),
00281 "PCI%02x:%02x.%x", bus,
00282 PCI_SLOT ( devfn ), PCI_FUNC ( devfn ) );
00283 pci->dev.desc.bus_type = BUS_TYPE_PCI;
00284 pci->dev.desc.location = PCI_BUSDEVFN (bus, devfn);
00285 pci->dev.desc.vendor = pci->vendor;
00286 pci->dev.desc.device = pci->device;
00287 pci->dev.desc.class = pci->class;
00288 pci->dev.desc.ioaddr = pci->ioaddr;
00289 pci->dev.desc.irq = pci->irq;
00290 pci->dev.parent = &rootdev->dev;
00291 list_add ( &pci->dev.siblings, &rootdev->dev.children);
00292 INIT_LIST_HEAD ( &pci->dev.children );
00293
00294
00295 if ( pci_probe ( pci ) == 0 ) {
00296
00297 pci = NULL;
00298 } else {
00299
00300 list_del ( &pci->dev.siblings );
00301 }
00302 }
00303 }
00304
00305 free ( pci );
00306 return 0;
00307
00308 err:
00309 free ( pci );
00310 pcibus_remove ( rootdev );
00311 return rc;
00312 }
00313
00314
00315
00316
00317
00318
00319 static void pcibus_remove ( struct root_device *rootdev ) {
00320 struct pci_device *pci;
00321 struct pci_device *tmp;
00322
00323 list_for_each_entry_safe ( pci, tmp, &rootdev->dev.children,
00324 dev.siblings ) {
00325 pci_remove ( pci );
00326 list_del ( &pci->dev.siblings );
00327 free ( pci );
00328 }
00329 }
00330
00331
00332 static struct root_driver pci_root_driver = {
00333 .probe = pcibus_probe,
00334 .remove = pcibus_remove,
00335 };
00336
00337
00338 struct root_device pci_root_device __root_device = {
00339 .dev = { .name = "PCI" },
00340 .driver = &pci_root_driver,
00341 };