source: bootcd/isolinux/syslinux-6.03/gpxe/src/drivers/bus/pciextra.c

Last change on this file was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

  • Property mode set to 100644
File size: 2.3 KB
RevLine 
[e16e8f2]1FILE_LICENCE ( GPL2_OR_LATER );
2
3#include <stdint.h>
4#include <gpxe/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 */
18int 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 */
62unsigned 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}
Note: See TracBrowser for help on using the repository browser.