Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Сканирование пространства шины PCI

3.2K
17 августа 2010 года
rihkov
42 / / 30.10.2005
Пожалуйста подскажите как правельно просканировать шину PCI и получить адреса установленных устройств, собрал маломальский код, но постоянно получаю нулевые результаты, подскажите что нужно зделать ???

Код:
// Сканирование шины PCI
// определяем значения смещений для пространства шины PCI
#define VENDOR_ID          0x00
#define DEVICE_ID          0x02
#define C_OD_E               0x04
#define STATUS             0x06
#define REVISION_ID        0x08
#define INTERFACE          0x09
#define SUBCLASS           0x0A
#define CLASSCODE          0x0B
#define CACHE_LINE_SIZE    0x0C
#define LATENCY_TIMER      0x0D
#define HEADER_TYPE        0x0E
#define BIST               0x0F
#define BASE_ADDRESS_0     0x10
#define BASE_ADDRESS_1     0x14
#define BASE_ADDRESS_2     0x18
#define BASE_ADDRESS_3     0x1C
#define BASE_ADDRESS_4     0x20
#define BASE_ADDRESS_5     0x24
#define CARDBUS_POINTER    0x28
#define SUBVEN_ID          0x2C
#define SUBSYSTEM_ID        0x2E
#define ROM_BASE_ADDRESS    0x30
#define INTERRUPT_LINE      0x3C
#define INTERRUPT_PIN       0x3D
#define MIN_GNT             0x3E
#define MAX_LAT             0x3F
//---------------------------------------------------------------------------

//---------------------------------------------------------------------------
int GetDeviceSlot(int iDevice, int iFunction)
{
   return ((((iDevice) & 0x1f) << 3) | ((iFunction) & 0x07));
}
//---------------------------------------------------------------------------
DWORD GetDevice(int iBusPCI, int iSlot, int iAddress)
{
   return (0x80000000L | ((iBusPCI & 0xff) << 16) | (iSlot << 8) | (iAddress & ~3));
}
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
// единственный аргумент функции определяет номер шины ( от 0 до 255 )
void ScanPCI(int iBusPCI)
{

   DWORD dwResult = 0;
   BYTE buffer[256];
   // создаем двойной цикл для перебора всех устройств
   for(int iDevice = 0; iDevice < 32; iDevice++)
   {
      for(int iFunction = 0; iFunction < 8; iFunction++)
      {
        memset(&buffer, 0, 256);
        // вычисляем номер очередного слота
        int iSlot = GetDeviceSlot(iDevice, iFunction);
        // проверяем поле Vendor ID для определения наличия устройства
        DWORD dwVendorID = 0;
        // получаем конфигурацию устройства
        dwResult = GetDevice(iBusPCI, iSlot, VENDOR_ID);
        // пишем в адресный порт параметры устройства
        SetPortVal(0xCF8, dwResult, 4);
        dwResult = 0;
        // читаем из порта данных идентификатор производителя
        GetPortVal(0xCFC, &dwResult, 4);
        // если полученное  значение равно 0 или 0xFFFFFFFF,  
        // выходим из вложенного цикла и продолжаем поиск
        if(dwVendorID == 0x00000000 || dwVendorID == 0xFFFFFFFF)
            break;
        DATA = 1;
        // если устройство присутствует, читаем его параметры
        // из конфигурационного пространства шины PCI
        for(int j = 1; j < 256; j++)
        {
          // получаем конфигурацию устройства
          dwResult = GetDevice(iBusPCI, iSlot, j);
          // пишем в адресный порт параметры устройства
          SetPortVal(0xCF8, dwResult, 4);
          // получаем из порта очередной байт
          GetPortVal(0xCFC + ( j&0x03 ), &dwResult, 1);
          // сохраняем полученный байт в буфер
          buffer[j] = dwResult;
          // здесь мы можем извлечь нужные данные из буфера и сохранить
          // их для последующего использования
          // например, получим номер прерывания для устройства
          // переменная uINT определена где-то ранее
          //uINT = buffer[INTERRUPT_LINE];
          // поле Header Type
          //uHeader = buffer[HEADER_TYPE];
          // поле Revision ID
          //uRevID = buffer[REVISION_ID];
          // поле Device ID
          dwDeviceID = ( (WORD) ( ( (BYTE) (buffer[DEVICE_ID]))  | ( ( (WORD) ( (BYTE) (buffer[DEVICE_ID] + 1) ) ) << 8) ) );
          // поле Cod_e
          dwC_od_e = ( (WORD) ( ( (BYTE) (buffer[C_OD_E]) )  | ( ( (WORD) ( (BYTE) (buffer[C_OD_E] + 1) ) ) << 8) ) );
          // поле Subsystem Vendor ID
          dwSubVendorID = ( (WORD) ( ( (BYTE) (buffer[SUBVEN_ID]) )  | ( ( (WORD) ( (BYTE) (buffer[SUBVEN_ID] + 1) ) ) << 8) ) );
          // базовый адрес 0
          WORD low = 0, high = 0;
          // получаем младшее слово адреса
          low = ( (WORD) ( ( (BYTE) (buffer[BASE_ADDRESS_0]) ) | ( ( (WORD) ( (BYTE) (buffer[BASE_ADDRESS_0] + 1) ) ) << 8) ) );
          // получаем старшее слово адреса
          high = ( (WORD) ( ( (BYTE) (buffer[BASE_ADDRESS_0] + 2) ) | ( ( (WORD) ( (BYTE) (buffer[BASE_ADDRESS_0] + 3) ) ) << 8) ) );
          // вычисляем полный адрес
          dwBaseAddress_0 = ( (LONG) ( ( (WORD) (low) ) |  ( ( (DWORD) ( (WORD) (high) ) ) << 16) ) );
        }
      }
   }
}
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог