Annotation of qemu/roms/ipxe/src/drivers/bus/pciextra.c, revision 1.1

1.1     ! root        1: FILE_LICENCE ( GPL2_OR_LATER );
        !             2: 
        !             3: #include <stdint.h>
        !             4: #include <ipxe/pci.h>
        !             5: 
        !             6: /**
        !             7:  * Look for a PCI capability
        !             8:  *
        !             9:  * @v pci              PCI device to query
        !            10:  * @v cap              Capability code
        !            11:  * @ret address                Address of capability, or 0 if not found
        !            12:  *
        !            13:  * Determine whether or not a device supports a given PCI capability.
        !            14:  * Returns the address of the requested capability structure within
        !            15:  * the device's PCI configuration space, or 0 if the device does not
        !            16:  * support it.
        !            17:  */
        !            18: int pci_find_capability ( struct pci_device *pci, int cap ) {
        !            19:        uint16_t status;
        !            20:        uint8_t pos, id;
        !            21:        uint8_t hdr_type;
        !            22:        int ttl = 48;
        !            23: 
        !            24:        pci_read_config_word ( pci, PCI_STATUS, &status );
        !            25:        if ( ! ( status & PCI_STATUS_CAP_LIST ) )
        !            26:                return 0;
        !            27: 
        !            28:        pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdr_type );
        !            29:        switch ( hdr_type & 0x7F ) {
        !            30:        case PCI_HEADER_TYPE_NORMAL:
        !            31:        case PCI_HEADER_TYPE_BRIDGE:
        !            32:        default:
        !            33:                pci_read_config_byte ( pci, PCI_CAPABILITY_LIST, &pos );
        !            34:                break;
        !            35:        case PCI_HEADER_TYPE_CARDBUS:
        !            36:                pci_read_config_byte ( pci, PCI_CB_CAPABILITY_LIST, &pos );
        !            37:                break;
        !            38:        }
        !            39:        while ( ttl-- && pos >= 0x40 ) {
        !            40:                pos &= ~3;
        !            41:                pci_read_config_byte ( pci, pos + PCI_CAP_LIST_ID, &id );
        !            42:                DBG ( "PCI Capability: %d\n", id );
        !            43:                if ( id == 0xff )
        !            44:                        break;
        !            45:                if ( id == cap )
        !            46:                        return pos;
        !            47:                pci_read_config_byte ( pci, pos + PCI_CAP_LIST_NEXT, &pos );
        !            48:        }
        !            49:        return 0;
        !            50: }
        !            51: 
        !            52: /**
        !            53:  * Find the size of a PCI BAR
        !            54:  *
        !            55:  * @v pci              PCI device
        !            56:  * @v reg              PCI register number
        !            57:  * @ret size           BAR size
        !            58:  *
        !            59:  * It should not be necessary for any Etherboot code to call this
        !            60:  * function.
        !            61:  */
        !            62: unsigned long pci_bar_size ( struct pci_device *pci, unsigned int reg ) {
        !            63:        uint16_t cmd;
        !            64:        uint32_t start, size;
        !            65: 
        !            66:        /* Save the original command register */
        !            67:        pci_read_config_word ( pci, PCI_COMMAND, &cmd );
        !            68:        /* Save the original bar */
        !            69:        pci_read_config_dword ( pci, reg, &start );
        !            70:        /* Compute which bits can be set */
        !            71:        pci_write_config_dword ( pci, reg, ~0 );
        !            72:        pci_read_config_dword ( pci, reg, &size );
        !            73:        /* Restore the original size */
        !            74:        pci_write_config_dword ( pci, reg, start );
        !            75:        /* Find the significant bits */
        !            76:        /* Restore the original command register. This reenables decoding. */
        !            77:        pci_write_config_word ( pci, PCI_COMMAND, cmd );
        !            78:        if ( start & PCI_BASE_ADDRESS_SPACE_IO ) {
        !            79:                size &= PCI_BASE_ADDRESS_IO_MASK;
        !            80:        } else {
        !            81:                size &= PCI_BASE_ADDRESS_MEM_MASK;
        !            82:        }
        !            83:        /* Find the lowest bit set */
        !            84:        size = size & ~( size - 1 );
        !            85:        return size;
        !            86: }

unix.superglobalmegacorp.com

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