3073|6

80

帖子

0

TA的资源

一粒金砂(初级)

楼主
 

关于I/O访问PCI设备问题 [复制链接]

我最近在学习PCI编程,在网上找到了下面一串代码
char bus;char device;

unsigned int ioa0,iod;

int scan( )

{

bus=0;device=0;

for(char i=0;i<5;i++) {

for(char j=0;j<32;j++) {

bus=i; device=j;

ioa0=0x80000000+bus*0x10000+(device*8)*0x100;

_outpd(0xcf8,ioa0);

iod=_inpd(0xcfc);

if (iod0= =0x905410b5) return 0;
}
}
retrn -1
}
哪位大哥可以帮忙解释一下红色部为什么要bus*0x10000,(device*8)*0x100,有什么作用?
谢谢~~~

最新回复

PCI CONFIG-ADDRESS配置空间 PCI设备给我们提供了两个32位的I/O空间,可以让我们进行读写操作。一个是CF8H另一个是CFCH,这两个端口对应PCI桥路的两个寄存器。当桥路看到CPU在局部总线对这两个I/O空间进行双字操作时,就将该I/O操作转变为PCI总线的配置操作。寄存器CF8h用于产生配置空间的地址(CONFIG-ADDRESS),寄存器CFCh用于保存配置空间的读写数据(CONFIG-DATA)。 Config-address 配置空间如下图,我们在访问PCI空间时,就是按下图所示进行遍历。 寄存器号:选择配置空间中的一个双字(32位); 功能号:选择多功能设备中的某一个功能,有八种功能(0—7); 设备号:在一条总线上选择32个设备中的一个。0—31; 总线号:从系统256条总线中选择一条,共256条。0—255; 尽管理论上有256条总线,但实际PC机上的PCI插槽的总线号总是1,我们访问0到15就够了。二、遍历PCI     在windows下遍歷PCI,需用到winio.dll。 1、        配置CF8H配置空間。即,將第31位(使能位)置1,總號,設備號,功能號,寄存器號相等均置0,得到(二進制:10000000000000000000000000000000)(16進制:0x80000000)。 2、        確認需遍歷多少條BUS,設備號,功能號,從0開始。 3、        使用CF8H空間對PCI配置空間進行遍歷訪問。再利用位移方式,將bus號  详情 回复 发表于 2010-1-30 20:35
点赞 关注

回复
举报

91

帖子

0

TA的资源

一粒金砂(初级)

沙发
 
沒有人知道嗎?
 
 

回复

61

帖子

0

TA的资源

一粒金砂(初级)

板凳
 
楼主去看下如何访问PCI配置空间就明白了
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

4
 
我看了地址空間,但還是沒有明白。2樓能不能說明白一點,謝謝~~~
 
 
 

回复

70

帖子

0

TA的资源

一粒金砂(初级)

5
 
这个需要看下 地址映射和总线与IO的配置。
 
 
 

回复

79

帖子

0

TA的资源

一粒金砂(初级)

6
 
#include
#include"winio.h"
#include "stdlib.h"
#include "stdio.h"
#define IO_AD 0xcf8
#define IO_DA 0xcfc
#pragma comment(lib,"winio.lib")
int main(int argc,CHAR *argv)
{
        DWORD Bus_No,Dev,Func,Rt_Val,VID,DID,Class1,Class2,Class3,count=0;       
        if(InitializeWinIo())
        {
                printf("VID   DID   BUS#   Dev#  Fun#\n");
                for(Bus_No=0;Bus_No<15;Bus_No++)
                {
                   for(Dev=0;Dev<32;Dev++)
                   {
                         for(Func=0;Func<8;Func++)
                         {
                                DWORD Val=0x80000000+(Bus_No<<16)+(Dev<<11)+(Func<<8);
                                SetPortVal(IO_AD,Val,4);
                                GetPortVal(IO_DA,&Rt_Val,4);
                                if(Rt_Val!=0xffffffff)
                                {
                                   count++;
                                   VID=Rt_Val&0xffff;
                                   DID=(Rt_Val>>16)&0xffff;
                                   printf("%04X  %04X  %02X     %02X   %02x\n",VID,DID,Bus_No,Func,Dev);
                                   if(Func==0)
                                   {
                                      Val=(Val&0xfffffff0)+0x0c;
                                          SetPortVal(IO_AD,Val,4);
                                          GetPortVal(IO_DA,&Rt_Val,4);
                                          Rt_Val=Rt_Val>>16;
                                          if((Rt_Val&0x80)==0)Func=8;
                                   }
                                  
                                }
                         }
                  
                   }
                }
                                   printf("Find PCI Device %d",count);
        }
        else
        {
          printf("Initialize Win IO Fail!\n");
          exit(255);
        }

   return 0;
}
 
 
 

回复

74

帖子

0

TA的资源

一粒金砂(初级)

7
 
PCI CONFIG-ADDRESS配置空间
PCI设备给我们提供了两个32位的I/O空间,可以让我们进行读写操作。一个是CF8H另一个是CFCH,这两个端口对应PCI桥路的两个寄存器。当桥路看到CPU在局部总线对这两个I/O空间进行双字操作时,就将该I/O操作转变为PCI总线的配置操作。寄存器CF8h用于产生配置空间的地址(CONFIG-ADDRESS),寄存器CFCh用于保存配置空间的读写数据(CONFIG-DATA)。
Config-address 配置空间如下图,我们在访问PCI空间时,就是按下图所示进行遍历。
寄存器号:选择配置空间中的一个双字(32位);
功能号:选择多功能设备中的某一个功能,有八种功能(0—7);
设备号:在一条总线上选择32个设备中的一个。0—31;
总线号:从系统256条总线中选择一条,共256条。0—255;
尽管理论上有256条总线,但实际PC机上的PCI插槽的总线号总是1,我们访问0到15就够了。二、遍历PCI
    在windows下遍歷PCI,需用到winio.dll。
1、        配置CF8H配置空間。即,將第31位(使能位)置1,總號,設備號,功能號,寄存器號相等均置0,得到(二進制:10000000000000000000000000000000)(16進制:0x80000000)。
2、        確認需遍歷多少條BUS,設備號,功能號,從0開始。
3、        使用CF8H空間對PCI配置空間進行遍歷訪問。再利用位移方式,將bus號<<16,設備號<<11,功能號<<8和0x80000000相加得到值Reval。
4、        利用winio中的SetPortVal(0xcf8,Reval,4);再用GetPortVal到CFCH空間將遍歷的PCI值取回。Pci=GetPortVal(0xcfc).
5、        用Pci的值與0xffffffff進行比較,來半判斷設備是否存在。

代码如下:
#include
#include"winio.h"
#include "stdlib.h"
#include "stdio.h"
#define IO_AD 0xcf8
#define IO_DA 0xcfc
#pragma comment(lib,"winio.lib")
int main(int argc,CHAR *argv)
{
        DWORD Bus_No,Dev,Func,Rt_Val,VID,DID,Class1,Class2,Class3,count=0;       
        if(InitializeWinIo())
        {
                printf("VID   DID   BUS#   Dev#  Fun#\n");
                for(Bus_No=0;Bus_No<15;Bus_No++)
                {
                   for(Dev=0;Dev<32;Dev++)
                   {
                         for(Func=0;Func<8;Func++)
                         {
                                DWORD Val=0x80000000+(Bus_No<<16)+(Dev<<11)+(Func<<8);
                                SetPortVal(IO_AD,Val,4);
                                GetPortVal(IO_DA,&Rt_Val,4);
                                if(Rt_Val!=0xffffffff)
                                {
                                   count++;
                                   VID=Rt_Val&0xffff;
                                   DID=(Rt_Val>>16)&0xffff;
                                   printf("%04X  %04X  %02X     %02X   %02x\n",VID,DID,Bus_No,Func,Dev);
                                   if(Func==0)
                                   {
                                      Val=(Val&0xfffffff0)+0x0c;
                                          SetPortVal(IO_AD,Val,4);
                                          GetPortVal(IO_DA,&Rt_Val,4);
                                          Rt_Val=Rt_Val>>16;
                                          if((Rt_Val&0x80)==0)Func=8;
                                   }
                                  
                                }
                         }
                  
                   }
                }
                                   printf("Find PCI Device %d",count);
        }
        else
        {
          printf("Initialize Win IO Fail!\n");
          exit(255);
        }

   return 0;
}
 
 
 

回复
您需要登录后才可以回帖 登录 | 注册

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/10 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表