pciextra.c
Go to the documentation of this file.00001 FILE_LICENCE ( GPL2_OR_LATER );
00002
00003 #include <stdint.h>
00004 #include <gpxe/pci.h>
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 int pci_find_capability ( struct pci_device *pci, int cap ) {
00019 uint16_t status;
00020 uint8_t pos, id;
00021 uint8_t hdr_type;
00022 int ttl = 48;
00023
00024 pci_read_config_word ( pci, PCI_STATUS, &status );
00025 if ( ! ( status & PCI_STATUS_CAP_LIST ) )
00026 return 0;
00027
00028 pci_read_config_byte ( pci, PCI_HEADER_TYPE, &hdr_type );
00029 switch ( hdr_type & 0x7F ) {
00030 case PCI_HEADER_TYPE_NORMAL:
00031 case PCI_HEADER_TYPE_BRIDGE:
00032 default:
00033 pci_read_config_byte ( pci, PCI_CAPABILITY_LIST, &pos );
00034 break;
00035 case PCI_HEADER_TYPE_CARDBUS:
00036 pci_read_config_byte ( pci, PCI_CB_CAPABILITY_LIST, &pos );
00037 break;
00038 }
00039 while ( ttl-- && pos >= 0x40 ) {
00040 pos &= ~3;
00041 pci_read_config_byte ( pci, pos + PCI_CAP_LIST_ID, &id );
00042 DBG ( "PCI Capability: %d\n", id );
00043 if ( id == 0xff )
00044 break;
00045 if ( id == cap )
00046 return pos;
00047 pci_read_config_byte ( pci, pos + PCI_CAP_LIST_NEXT, &pos );
00048 }
00049 return 0;
00050 }
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 unsigned long pci_bar_size ( struct pci_device *pci, unsigned int reg ) {
00063 uint16_t cmd;
00064 uint32_t start, size;
00065
00066
00067 pci_read_config_word ( pci, PCI_COMMAND, &cmd );
00068
00069 pci_read_config_dword ( pci, reg, &start );
00070
00071 pci_write_config_dword ( pci, reg, ~0 );
00072 pci_read_config_dword ( pci, reg, &size );
00073
00074 pci_write_config_dword ( pci, reg, start );
00075
00076
00077 pci_write_config_word ( pci, PCI_COMMAND, cmd );
00078 if ( start & PCI_BASE_ADDRESS_SPACE_IO ) {
00079 size &= PCI_BASE_ADDRESS_IO_MASK;
00080 } else {
00081 size &= PCI_BASE_ADDRESS_MEM_MASK;
00082 }
00083
00084 size = size & ~( size - 1 );
00085 return size;
00086 }