Annotation of qemu/roms/ipxe/src/drivers/bus/pci.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (C) 2006 Michael Brown <[email protected]>.
                      3:  *
                      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.
                      6:  *
                      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.
                     11:  *
                     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.
                     16:  *
                     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.
                     20:  */
                     21: 
                     22: FILE_LICENCE ( GPL2_OR_LATER );
                     23: 
                     24: #include <stdint.h>
                     25: #include <stdlib.h>
                     26: #include <stdio.h>
                     27: #include <string.h>
                     28: #include <errno.h>
                     29: #include <ipxe/tables.h>
                     30: #include <ipxe/device.h>
                     31: #include <ipxe/pci.h>
                     32: 
                     33: /** @file
                     34:  *
                     35:  * PCI bus
                     36:  *
                     37:  */
                     38: 
                     39: static void pcibus_remove ( struct root_device *rootdev );
                     40: 
                     41: /**
                     42:  * Read PCI BAR
                     43:  *
                     44:  * @v pci              PCI device
                     45:  * @v reg              PCI register number
                     46:  * @ret bar            Base address register
                     47:  *
                     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.
                     54:  */
                     55: static unsigned long pci_bar ( struct pci_device *pci, unsigned int reg ) {
                     56:        uint32_t low;
                     57:        uint32_t high;
                     58: 
                     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 );
                     63:                if ( high ) {
                     64:                        if ( sizeof ( unsigned long ) > sizeof ( uint32_t ) ) {
                     65:                                return ( ( ( uint64_t ) high << 32 ) | low );
                     66:                        } else {
                     67:                                DBGC ( pci, PCI_FMT " unhandled 64-bit BAR "
                     68:                                       "%08x%08x\n",
                     69:                                       PCI_ARGS ( pci ), high, low );
                     70:                                return PCI_BASE_ADDRESS_MEM_TYPE_64;
                     71:                        }
                     72:                }
                     73:        }
                     74:        return low;
                     75: }
                     76: 
                     77: /**
                     78:  * Find the start of a PCI BAR
                     79:  *
                     80:  * @v pci              PCI device
                     81:  * @v reg              PCI register number
                     82:  * @ret start          BAR start address
                     83:  *
                     84:  * Reads the specified PCI base address register, and returns the
                     85:  * address portion of the BAR (i.e. without the flags).
                     86:  *
                     87:  * If the address exceeds the size of an unsigned long (i.e. if a
                     88:  * 64-bit BAR has a non-zero high dword on a 32-bit machine), the
                     89:  * return value will be zero.
                     90:  */
                     91: unsigned long pci_bar_start ( struct pci_device *pci, unsigned int reg ) {
                     92:        unsigned long bar;
                     93: 
                     94:        bar = pci_bar ( pci, reg );
                     95:        if ( (bar & PCI_BASE_ADDRESS_SPACE) == PCI_BASE_ADDRESS_SPACE_MEMORY ){
                     96:                return ( bar & PCI_BASE_ADDRESS_MEM_MASK );
                     97:        } else {
                     98:                return ( bar & PCI_BASE_ADDRESS_IO_MASK );
                     99:        }
                    100: }
                    101: 
                    102: /**
                    103:  * Read membase and ioaddr for a PCI device
                    104:  *
                    105:  * @v pci              PCI device
                    106:  *
                    107:  * This scans through all PCI BARs on the specified device.  The first
                    108:  * valid memory BAR is recorded as pci_device::membase, and the first
                    109:  * valid IO BAR is recorded as pci_device::ioaddr.
                    110:  *
                    111:  * 64-bit BARs are handled automatically.  On a 32-bit platform, if a
                    112:  * 64-bit BAR has a non-zero high dword, it will be regarded as
                    113:  * invalid.
                    114:  */
                    115: static void pci_read_bases ( struct pci_device *pci ) {
                    116:        unsigned long bar;
                    117:        int reg;
                    118: 
                    119:        for ( reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg += 4 ) {
                    120:                bar = pci_bar ( pci, reg );
                    121:                if ( bar & PCI_BASE_ADDRESS_SPACE_IO ) {
                    122:                        if ( ! pci->ioaddr )
                    123:                                pci->ioaddr = 
                    124:                                        ( bar & PCI_BASE_ADDRESS_IO_MASK );
                    125:                } else {
                    126:                        if ( ! pci->membase )
                    127:                                pci->membase =
                    128:                                        ( bar & PCI_BASE_ADDRESS_MEM_MASK );
                    129:                        /* Skip next BAR if 64-bit */
                    130:                        if ( bar & PCI_BASE_ADDRESS_MEM_TYPE_64 )
                    131:                                reg += 4;
                    132:                }
                    133:        }
                    134: }
                    135: 
                    136: /**
                    137:  * Enable PCI device
                    138:  *
                    139:  * @v pci              PCI device
                    140:  *
                    141:  * Set device to be a busmaster in case BIOS neglected to do so.  Also
                    142:  * adjust PCI latency timer to a reasonable value, 32.
                    143:  */
                    144: void adjust_pci_device ( struct pci_device *pci ) {
                    145:        unsigned short new_command, pci_command;
                    146:        unsigned char pci_latency;
                    147: 
                    148:        pci_read_config_word ( pci, PCI_COMMAND, &pci_command );
                    149:        new_command = ( pci_command | PCI_COMMAND_MASTER |
                    150:                        PCI_COMMAND_MEM | PCI_COMMAND_IO );
                    151:        if ( pci_command != new_command ) {
                    152:                DBGC ( pci, PCI_FMT " device not enabled by BIOS! Updating "
                    153:                       "PCI command %04x->%04x\n",
                    154:                       PCI_ARGS ( pci ), pci_command, new_command );
                    155:                pci_write_config_word ( pci, PCI_COMMAND, new_command );
                    156:        }
                    157: 
                    158:        pci_read_config_byte ( pci, PCI_LATENCY_TIMER, &pci_latency);
                    159:        if ( pci_latency < 32 ) {
                    160:                DBGC ( pci, PCI_FMT " latency timer is unreasonably low at "
                    161:                       "%d. Setting to 32.\n", PCI_ARGS ( pci ), pci_latency );
                    162:                pci_write_config_byte ( pci, PCI_LATENCY_TIMER, 32);
                    163:        }
                    164: }
                    165: 
                    166: /**
                    167:  * Read PCI device configuration
                    168:  *
                    169:  * @v pci              PCI device
                    170:  * @ret rc             Return status code
                    171:  */
                    172: int pci_read_config ( struct pci_device *pci ) {
                    173:        uint32_t tmp;
                    174: 
                    175:        /* Check for physical device presence */
                    176:        pci_read_config_dword ( pci, PCI_VENDOR_ID, &tmp );
                    177:        if ( ( tmp == 0xffffffff ) || ( tmp == 0 ) )
                    178:                return -ENODEV;
                    179: 
                    180:        /* Populate struct pci_device */
                    181:        pci->vendor = ( tmp & 0xffff );
                    182:        pci->device = ( tmp >> 16 );
                    183:        pci_read_config_dword ( pci, PCI_REVISION, &tmp );
                    184:        pci->class = ( tmp >> 8 );
                    185:        pci_read_config_byte ( pci, PCI_INTERRUPT_LINE, &pci->irq );
                    186:        pci_read_bases ( pci );
                    187: 
                    188:        /* Initialise generic device component */
                    189:        snprintf ( pci->dev.name, sizeof ( pci->dev.name ),
                    190:                   "PCI%02x:%02x.%x", PCI_BUS ( pci->busdevfn ),
                    191:                   PCI_SLOT ( pci->busdevfn ), PCI_FUNC ( pci->busdevfn ) );
                    192:        pci->dev.desc.bus_type = BUS_TYPE_PCI;
                    193:        pci->dev.desc.location = pci->busdevfn;
                    194:        pci->dev.desc.vendor = pci->vendor;
                    195:        pci->dev.desc.device = pci->device;
                    196:        pci->dev.desc.class = pci->class;
                    197:        pci->dev.desc.ioaddr = pci->ioaddr;
                    198:        pci->dev.desc.irq = pci->irq;
                    199:        INIT_LIST_HEAD ( &pci->dev.siblings );
                    200:        INIT_LIST_HEAD ( &pci->dev.children );
                    201: 
                    202:        return 0;
                    203: }
                    204: 
                    205: /**
                    206:  * Find driver for PCI device
                    207:  *
                    208:  * @v pci              PCI device
                    209:  * @ret rc             Return status code
                    210:  */
                    211: int pci_find_driver ( struct pci_device *pci ) {
                    212:        struct pci_driver *driver;
                    213:        struct pci_device_id *id;
                    214:        unsigned int i;
                    215: 
                    216:        for_each_table_entry ( driver, PCI_DRIVERS ) {
                    217:                for ( i = 0 ; i < driver->id_count ; i++ ) {
                    218:                        id = &driver->ids[i];
                    219:                        if ( ( id->vendor != PCI_ANY_ID ) &&
                    220:                             ( id->vendor != pci->vendor ) )
                    221:                                continue;
                    222:                        if ( ( id->device != PCI_ANY_ID ) &&
                    223:                             ( id->device != pci->device ) )
                    224:                                continue;
                    225:                        pci_set_driver ( pci, driver, id );
                    226:                        return 0;
                    227:                }
                    228:        }
                    229:        return -ENOENT;
                    230: }
                    231: 
                    232: /**
                    233:  * Probe a PCI device
                    234:  *
                    235:  * @v pci              PCI device
                    236:  * @ret rc             Return status code
                    237:  *
                    238:  * Searches for a driver for the PCI device.  If a driver is found,
                    239:  * its probe() routine is called.
                    240:  */
                    241: int pci_probe ( struct pci_device *pci ) {
                    242:        int rc;
                    243: 
                    244:        DBGC ( pci, PCI_FMT " (%04x:%04x) has driver \"%s\"\n",
                    245:               PCI_ARGS ( pci ), pci->vendor, pci->device, pci->id->name );
                    246:        DBGC ( pci, PCI_FMT " has mem %lx io %lx irq %d\n",
                    247:               PCI_ARGS ( pci ), pci->membase, pci->ioaddr, pci->irq );
                    248: 
                    249:        if ( ( rc = pci->driver->probe ( pci ) ) != 0 ) {
                    250:                DBGC ( pci, PCI_FMT " probe failed: %s\n",
                    251:                       PCI_ARGS ( pci ), strerror ( rc ) );
                    252:                return rc;
                    253:        }
                    254: 
                    255:        return 0;
                    256: }
                    257: 
                    258: /**
                    259:  * Remove a PCI device
                    260:  *
                    261:  * @v pci              PCI device
                    262:  */
                    263: void pci_remove ( struct pci_device *pci ) {
                    264:        pci->driver->remove ( pci );
                    265:        DBGC ( pci, PCI_FMT " removed\n", PCI_ARGS ( pci ) );
                    266: }
                    267: 
                    268: /**
                    269:  * Probe PCI root bus
                    270:  *
                    271:  * @v rootdev          PCI bus root device
                    272:  *
                    273:  * Scans the PCI bus for devices and registers all devices it can
                    274:  * find.
                    275:  */
                    276: static int pcibus_probe ( struct root_device *rootdev ) {
                    277:        struct pci_device *pci = NULL;
                    278:        unsigned int num_bus;
                    279:        unsigned int busdevfn;
                    280:        uint8_t hdrtype = 0;
                    281:        int rc;
                    282: 
                    283:        num_bus = pci_num_bus();
                    284:        for ( busdevfn = 0 ; busdevfn < PCI_BUSDEVFN ( num_bus, 0, 0 ) ;
                    285:              busdevfn++ ) {
                    286: 
                    287:                /* Allocate struct pci_device */
                    288:                if ( ! pci )
                    289:                        pci = malloc ( sizeof ( *pci ) );
                    290:                if ( ! pci ) {
                    291:                        rc = -ENOMEM;
                    292:                        goto err;
                    293:                }
                    294:                memset ( pci, 0, sizeof ( *pci ) );
                    295:                pci_init ( pci, busdevfn );
                    296:                        
                    297:                /* Skip all but the first function on
                    298:                 * non-multifunction cards
                    299:                 */
                    300:                if ( PCI_FUNC ( busdevfn ) == 0 ) {
                    301:                        pci_read_config_byte ( pci, PCI_HEADER_TYPE,
                    302:                                               &hdrtype );
                    303:                } else if ( ! ( hdrtype & 0x80 ) ) {
                    304:                        continue;
                    305:                }
                    306: 
                    307:                /* Read device configuration */
                    308:                if ( ( rc = pci_read_config ( pci ) ) != 0 )
                    309:                        continue;
                    310: 
                    311:                /* Look for a driver */
                    312:                if ( ( rc = pci_find_driver ( pci ) ) != 0 ) {
                    313:                        DBGC ( pci, PCI_FMT " (%04x:%04x) has no driver\n",
                    314:                               PCI_ARGS ( pci ), pci->vendor, pci->device );
                    315:                        continue;
                    316:                }
                    317: 
                    318:                /* Add to device hierarchy */
                    319:                pci->dev.parent = &rootdev->dev;
                    320:                list_add ( &pci->dev.siblings, &rootdev->dev.children);
                    321: 
                    322:                /* Look for a driver */
                    323:                if ( ( rc = pci_probe ( pci ) ) == 0 ) {
                    324:                        /* pcidev registered, we can drop our ref */
                    325:                        pci = NULL;
                    326:                } else {
                    327:                        /* Not registered; re-use struct pci_device */
                    328:                        list_del ( &pci->dev.siblings );
                    329:                }
                    330:        }
                    331: 
                    332:        free ( pci );
                    333:        return 0;
                    334: 
                    335:  err:
                    336:        free ( pci );
                    337:        pcibus_remove ( rootdev );
                    338:        return rc;
                    339: }
                    340: 
                    341: /**
                    342:  * Remove PCI root bus
                    343:  *
                    344:  * @v rootdev          PCI bus root device
                    345:  */
                    346: static void pcibus_remove ( struct root_device *rootdev ) {
                    347:        struct pci_device *pci;
                    348:        struct pci_device *tmp;
                    349: 
                    350:        list_for_each_entry_safe ( pci, tmp, &rootdev->dev.children,
                    351:                                   dev.siblings ) {
                    352:                pci_remove ( pci );
                    353:                list_del ( &pci->dev.siblings );
                    354:                free ( pci );
                    355:        }
                    356: }
                    357: 
                    358: /** PCI bus root device driver */
                    359: static struct root_driver pci_root_driver = {
                    360:        .probe = pcibus_probe,
                    361:        .remove = pcibus_remove,
                    362: };
                    363: 
                    364: /** PCI bus root device */
                    365: struct root_device pci_root_device __root_device = {
                    366:        .dev = { .name = "PCI" },
                    367:        .driver = &pci_root_driver,
                    368: };

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.