Chinaunix

标题: 请问如何遍历并获取PCI配置空间的数据 [打印本页]

作者: netdoger    时间: 2012-09-18 09:26
标题: 请问如何遍历并获取PCI配置空间的数据
我是在网上看到的,它是用DJGPP的C语言写的,可是我取到的Vendor ID都是FFFFh,
我是从XP下先运行DJGPP网站提供的BAT文件,然后再运行RHIDE(如果在纯DOS下运行
bat文件,系统提示出错),
请问我的代码错在哪了,如何修改?
请看:
#include <stdio.h>
#include <dpmi.h>
#include <pc.h>

typedef unsigned long      UDWORD;
typedef unsigned short int UWORD;

int main()
{

    __dpmi_regs regs;
    UWORD flags;
    UDWORD i, busNo, deviceNo, funcNo, regVal, retVal;
    UWORD  vendorID, devID, class1, class2, class3;

        regs.x.ax = 0xb108;
    regs.x.bx =0x10;
        regs.x.di=0;
    __dpmi_int(0x1a, &regs);
    flags=regs.x.flags;

        if((flags & 0x01)==0)
        {
                printf("\nSupport PCI BIOS.";
        }
        else
        {
                printf("\nNot Support PCI BIOS.";
                return 1;

        }

        UDWORD i, busNo, deviceNo, funcNo, regVal, retVal;
        UWORD  vendorID, devID, class1, class2, class3;

        i = 0;
        for(busNo = 0; busNo < 5; busNo++)               // bus No
        {                                       
           for(deviceNo = 0; deviceNo < 32; deviceNo++)  // device no
           {      
                 for (funcNo = 0; funcNo < 8; funcNo++)     // Function No
                  {
                          regVal = 0x80000000                       // bit31 使能
                 + (busNo << 16)                        // Bus No
                 + (deviceNo << 11)                     // Device No
                 + (funcNo << ;                       // Function No
            
                outportl(0x0CF8, regVal);
                retVal = inportl(0x0CFC);                  // 得到配置空间偏移为0的双字
                         if ((UWORD)retVal != 0xffff)                  // 设备存在
                          {   
                                  i++;
                                  vendorID = retVal & 0xffff;                    // 得到供应商代码
                  devID    = (retVal >> 16) & 0xffff;            // 得到设备代码
                  regVal += 0x08;                                // 得到配置空间偏移为08H的双字
                  outportl(0x0CF8, regVal);
                  retVal = inportl(0x0CFC);
                  retVal = retVal >> 8;                         // 滤掉版本号
                  class3 = retVal & 0x0FF;                      // 得到三个分类代码
                  class2 = (retVal >> &0x0FF;
                  class1 = (retVal >> &0x0FF;
                  printf("\n%03d   %04x/%04x       %02x       %02x       %02x      %02x-%02x-%02x",
                               i, vendorID, devID, busNo, deviceNo, funcNo, class1, class2, class3);
                            if (funcNo == 0)                    // 如果是单功能设备,则不再查funcNo>0的设备
                              {     
                                          regVal = (regVal & 0xFFFFFFF0) + 0x0C;  //配置空间偏移0X0C
                      outportl(0x0CF8, regVal);
                      retVal = inportl(0x0CFC);
                      retVal = retVal >> 16;                 //偏移0X0E为投标类型字段
                      if ((retVal & 0x80) == 0) funcNo = 8;  //bit 7为0表示单功能设备,不再查该设备的其他功能
                                  }
                          }
                  }
           }
        }


    return 0;
}
作者: netdoger    时间: 2012-09-18 15:01
补充:在纯DOS会出现:Load error:no DPMI-Get csdpmi*b.zip
请问怎么解决?
作者: selfrun    时间: 2012-09-18 18:08
v86模式不允许直接访问pci寄存器吧
作者: folklore    时间: 2012-09-18 19:30
回复 3# selfrun


    不可以访问。
在DOS下直接就可以访问了。
看看PCI的总线的资料,自已写一个吧。不难,就是有点不麻烦。




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2