精华内容
下载资源
问答
  • 【PCIe】配置空间

    万次阅读 多人点赞 2016-06-07 15:11:49
    介绍PCI/PCIe配置空间

    简介

    PCI/PCIe设备有自己的独立地址空间,这部分空间会映射到整个系统的地址空间。

    映射地址在BIOS/UEFI下指定(如果有的话,对于使用非BIOS启动的OS,不清楚),它有两种类型,一种是MMIO,一种是IO。对于MMIO的访问,跟访问内存的方式一样,它从称为PCIEXBAR的基地址开始,有很大的一段空间,这个PCIEXBAR的值根据不同的平台可能不同,大致可能值有0xC0000000、0xE0000000等,关于这个值是怎么使用的后面的章节会讲到;对于IO,它是一种比较老的访问PCI/PCIe设备的方式,而且占有的空间相比MMIO非常小,好像只有64K的空间。

    PCI/PCIe设备使用的空间也有两个部分,一部分称为配置空间(通过MMIO);另一部分通过配置空间的BAR寄存器指定,是设备实现功能所需要用到的地址空间(有MMIO也有IO, 不过IO用的比较少了)。

    PCI/PCIe配置空间的访问方式

    PCI/PCIe设备的配置空间通过PCIEXBAR加上设备的Bus、Device、Fun号的转换来得到,BDF到地址的转换关系如下:

    /**
      Macro that converts PCI Bus, PCI Device, PCI Function and PCI Register to an
      address that can be passed to the PCI Library functions.
    
      @param  Bus       PCI Bus number. Range 0..255.
      @param  Device    PCI Device number. Range 0..31.
      @param  Function  PCI Function number. Range 0..7.
      @param  Register  PCI Register number. Range 0..255 for PCI. Range 0..4095
                        for PCI Express.
    
      @return The encoded PCI address.
    
    **/
    #define PCI_LIB_ADDRESS(Bus,Device,Function,Register)   \
      (((Register) & 0xfff) | (((Function) & 0x07) << 12) | (((Device) & 0x1f) << 15) | (((Bus) & 0xff) << 20))
    

    其中的Register是具体要访问的寄存器。

    这是最常用的一种方式,通过将B/D/F转换成MMIO的地址,之后就可以通过MMIO的方式来访问,下面是一个例子:

    UINT8
    EFIAPI
    PciExpressRead8 (
      IN      UINTN                     Address
      )
    {
      ASSERT_INVALID_PCI_ADDRESS (Address);
      return MmioRead8 ((UINTN) GetPciExpressBaseAddress () + Address);
    }

    不过这里有个问题,通过PCI_LIB_ADDRESS得到的并不是实际的系统地址空间,它算是一个偏移,还需要加上一个基地址(就是这个通过函数GetPciExpressBaseAddress()得到的)。在UEFI中这个基地址被设置成一个PCD变量:PcdPciExpressBaseAddress。它的值根据不同平台可能会不同。

    不过重点不是它的值,重点是如何设置这个值,因为只有设置了这个值才能使用上面说的方式来读写PCI/PCIe配置空间。

    而PCIEXBAR也是要写到PCI设备的配置空间中的,它会被写到B0/D0/F0/R060h这个寄存器(不同平台可能不同)。

    这里就遇到了一个问题,该通过什么方式来写这个值呢?

    实际上,需要注意几点:

    1. 上述提供的访问PCI/PCIe配置空间的方式是PCIe的方式;

    2. 早期在没有PCIe的时候,要访问配置空间时,使用的是两个IO端口,CFCh和CF8h,通过往一个端口指定寄存器,另一个端口写值的方式为指定寄存器赋值。

    所以我们要注意,有两个配置空间的方式:

    1. 传统方式,写IO端口CFCh和CF8h。只能访问PCI/PCIe设备的开始256个字节(因为PCI设备的配置空间本来就只有256个字节);

    2. PCIe的方式,就是上面提到的方式,它可以方位4K个字节的配置空间。

    PCI配置空间

    由于PCI/PCIe设备分为Bridge和Agent两种,所以配置空间也有两种类型:

    其中Agent的配置空间类型称为Type 00h:

    简单介绍其中的几个寄存器的意义:

    Vendor ID,Device ID:标记了一个设备的生产厂商和具体的设备,比如Intel的设备Vendor ID通常是0x8086,Device ID就需要厂家自定义了,总之能够识别到具体是哪个设备就可以了。

    Status:设备状态字,具体每个BIT的意义见下图:

    Command:设备状态字:

    Base Address Registers:决定PCI/PCIe设备空间映射到系统空间具体位置的寄存器,映射方式有两种,分别是IO和Memory映射:

    处理器系统资源分为IO资源和MMIO资源两种,因此PCI/PCIe空间地址对应也有两种。

    下面是Bridge的配置空间,它的类型被称为Type 01h:

    Type 01h中也有Vendor ID,Device ID,Status,Command等寄存器。

    另外需要注意的是这里的BAR计算得到的系统空间是该桥下挂的所有设备的系统空间的总和。

    另外Subordinate Bus Number、Secondary Bus Number和Primary Bus Number,这些寄存器共同确定了该桥上行和下行的所有Bus号。

    PCIe配置空间

    PCIe是在PCI基础上发展的协议,PCIe也有上述的PCI配置空间,并且在此基础之上进行了扩展,其扩展形式是通过一种称为Capability的寄存器块来完成的。

    PCI配置空间的大小是256个字节,即0x00~0xFF,而PCIe的配置空间扩大到了0x00~0xFFF,下图是具体的布局。

    在原来的配置空间中,有一个寄存器指定了第一个Capability的位置,而第一个Capability又指定下一个Capability,构成了一串Capability,具体如下图所示:

    各个不同的Capability的作用不同,且不同的设备有不同的Capability,在这里不一一介绍了。

    其它说明

    处理器系统中会为所有的PCI/PCIe设备留足足够的空间,但是几乎没有系统会满配,所以很多的配置空间实际上是空的,此时如果去访问,就会得到全FF,表示设备不存在。

    下面是linux下访问PCI/PCIe配置空间的一个例子:

    注:以上是一个Intel网卡的PCI/PCIe配置空间,这是虚拟机下的结果,真实机器上可能有所不同。

    展开全文
  • PCIe架构下定义了4中地址空间:Memory空间、IO空间、配置空间和message空间。 我们先看一下PCIe spec关于这四种空间的定义: (1)配置空间 Configuration Space One of the four address spaces within the PCI ...

    1、 4种空间迷魂阵
    PCIe架构下定义了4种地址空间:Memory空间、IO空间、配置空间和message空间。

    我们先看一下PCIe spec关于这四种空间的定义:

    (1)配置空间 Configuration Space

    One of the four address spaces within the PCI Express architecture. Packets with a Configuration Space address are used to configure Functions。

    (2)IO空间 I/O Space

    One of the four address spaces of the PCI Express architecture. Identical to the I/O Space defined in the PCI Local Bus Specification

    (3)memory空间 Memory Space

    One of the four address spaces of the PCI Express architecture. Identical to the Memory Space defined in PCI 3.0

    (4)message空间 Message Space
    One of the four address spaces of the PCI Express architecture

    看完介绍是不是更懵X了,如果没有懵X说明这篇文章不适合你了,如果懵X了就继续。

    message空间其实就是用来report带内的message和event的(比如MSI中断、电源管理消息等),其实就是通过带内message transaction的方式来代替带外信号,用message的好处就是可以省去许多带外信号。

    下面是PCIe spec中关于message space描述的原话:

    The transaction Layer supports four address spaces: it includes the three PCI address spaces (memory, I/O, and configuration) and adds Message Space. This specification uses Message Space to support all prior sideband signals, such as interrupts, power-management requests, and so on, as in-band Message transactions. You could think of PCI Express Message transactions as “virtual wires” since their effect is to eliminate the wide array of sideband signals currently used in a platform implementation.

    抛开第4种message空间先不谈,先看其他三种PCI 架构就定义的地址空间:Memory空间、IO空间、配置空间。说到memory空间和IO空间就不得不说统一编址和独立编址的问题。

    2、 统一编址和独立编址导致IO空间和Memory空间分离
    在这里插入图片描述
    X86采用独立编址的方式,将memory操作与外设IO操作分开了,才有了memory空间和IO空间的区分。X86平台CPU内部对内存和外设寄存器访问的指令也是不同的。

    IO空间:

    访问外部设备寄存器的地址区域,(PCI支持4GB的IO空间,但是x86平台为64KB)。

    memory空间:

    访问内存的地址空间,32位平台为4G。 此memory空间和main memory(平时常说的内存或者主存)是两个概念,32bit平台下CPU memory地址总线只能寻址到4G,这4G空间包括main memory、外设IO空间映射(MMIO)等,不能全给main memory,因此32bit的CPU是无法配置4G内存的。

    PCIe 配置空间:

    PCIe spec规定了所有PCIe设备(除了host bus bridge外)必须实现配置空间,说白了就是PCI-SIG规定了一种独立于memory空间的PCIe设备访问(读写、配置)机制(说白了就是一堆按规则排列的reg)。PCI-SIG详细规定了PCIe设备reg的排列(每个capability id reg的后面4Byte会保存next capability的起始地址,这样方便芯片厂商扩展reg,并且PCIe驱动软件天然可以使用list来管理这些reg)。
    在这里插入图片描述

    3、 三角关系

    X86的CPU可以直接访问memory空间和IO空间,但是不能直接访问PCIe配置空间(原因很简单,X86的CPU只有memory指令和IO指令,没有配置指令)。因此,需要把PCIe配置空间映射到memory空间或者IO空间(一般不推荐映射到IO空间)。或者说CPU访问PCIe配置空间需要一个翻译官(RC)。这个翻译官是干好事的(帮CPU的memory访问或者IO访问转换成PCIe域的请求),不是给鬼子带路的汉奸。

    在X86系统中,IO方式的翻译官就是CONFIG_DATA和CONFIG_ADDRESS,这个两个位于IO空间的端口。这就是所谓的PCI的CAM方式,只能访问PCI兼容的配置空间(前面256Byte,从下图中也可看到register number只有8bit,所有只能访问256Byte。但是有些芯片比较鸡贼,会把reserved的bit24到30用起来,使用bit24-27作为extended register number,和bit0-7的register number组合这样可以扩展到4K,不过这种扩展属于芯片的私有行为,并不是所有芯片都支持)。

    在X86系统中,Memroy方式的翻译官就是MCFG(memory mapped configuration space base address description table可以通过cat /proc/iomem查看PCI MMCONFIG得到在memory空间的映射)其实就是bus 0 dev 0 function 0 的BASE地址。这就是所谓的PCIe的ECAM方式,可以访问PCIe全部4K配置空间。
    可以通过cat/proc/iomem | grep MMCONFIG得到MMCONFIG的base地址,然后使用busbox下面的devmem按照表格7-1的规则访问配置空间(下面程序找了0:3.1和0:0.0做了下实验),但是这种方式存在顺序问题,见PCIe Spec
    在这里插入图片描述
    ECAM把memory事务从host CPU转换成PCIe fabric配置请求。这种转换对应软件来说存在潜在的顺序问题,因为写memory地址是典型的post事务,但是写配置空间是non post的请求。
    软件无法知道什么时候,完成者完成了post事务。这种场景下(ECAM访问),软件必须要知道完成者已经完成了post请求,软件通常用回读刚写过location的这种方式来确定完成者是否完成。对于遵守PCI order规则的系统,read 事务必须要在post写完成后才能完成。然而,由于PCI order规则允许non post写事务和read事务进行乱序处理,CPU必须等待PCIe fabric上non-post写请求完成来确保完成者完成了这个事务(也就说,由于允许乱序non post写事务插了read的队)。
    举个例子,软件期望通过ECAM的方式写device的Base address reg,然后读取memory-map的区域的base address reg的位置。如果软件发出memory-map读请求乱序了,在配置写请求达到前就达到,将会引起不可预知的结果。
    为了阻止这个问题,处理器和主桥必须确保有一种方式可以让软件确定什么时候使用ECAM的写请求被完成者完成。
    在这里插入图片描述
    在这里插入图片描述

    BAR(base address registers)就是为了把设备的内部各种资源映射到IO空间(IO BAR)或者memory 空间(memory BAR)。
    在这里插入图片描述
    关于IO方式和memory方式访问PCIe配置空间的具体实现,参考
    https://blog.csdn.net/huangkangying/article/details/50570612
    https://blog.csdn.net/mao0514/article/details/26072229
    https://blog.csdn.net/xingqingly/article/details/45695739
    https://zhuanlan.zhihu.com/p/34047690
    http://developer.amd.com/wordpress/media/2012/10/pci%20-%20pci%20express%20configuration%20space%20access.pdf

    展开全文
  • PCI的配置空间

    千次阅读 2013-02-21 15:32:51
    PCI的配置空间 主要讨论如何去访问PCI配置空间和描述PCI设备的配置空间的定义和使用规则。理论上如何访问PCI配置空间的问题是属于总线操作的一部分,但是和配置空间有着密切联系,有必要一起讨论。   PCI的配置...

    PCI的配置空间

    主要讨论如何去访问PCI配置空间和描述PCI设备的配置空间的定义和使用规则。理论上如何访问PCI配置空间的问题是属于总线操作的一部分,但是和配置空间有着密切联系,有必要一起讨论。

     

    PCI的配置空间一共256 bytes大小,可以分成两个部分:头部和独立部分。这里主要讨论header部分的register。由于PCI的架构特性,PCI分为普通PCI设备和PCI桥。PCI桥也可以认为是一个pci设备,其配置空间的header部分稍微复杂一点。可以参阅PCI-PCI bridge spec来了解更多情况。

    下图是pci架构的级联图。不同的bus就是通过Bridge来连接的。每个PCI bus上都可以挂载多个PCI设备,相同bus上的各个设备是以PCI device NO.来区分的。所以在逻辑上来讲,在PCI总线系统中的各个PCI设备都会有一个特定而唯一的逻辑地址---Bus_NO + Device_NO + Function_NO. 总线上的逻辑信号就译码每个设备的不同逻辑地址来找到对应的PCI设备,并访问其配置i空间。

     

    由于PCI总线在开机之后任何时候都可以去访问,所以我们可以在POST阶段或者系统中随时可以依据设备的总线逻辑地址去访问该PCI设备,每个pci设备都会有个唯一对应的总线地址的,比如下图。

    这个是在本人电脑上读到的EHCI对应的总线地址。BUSNO=0;DeviceNO=29;FunctionNO=0.所以如果要访问这个pci设备-EHCI的话,就要使用PCI配置空间访问函数中输入这个地址。当然如果要访问配置空间的某个register的话,那么输入的参数应该是(BusNO, DeviceNO, FunctionNo, Register)。

     

    访问PCI配置空间的算法

    理所当然,说到这里就必然涉及到如何去访问pci总线,其中的算法是怎样的呢?PCI协议中定义了一组IO端口CF8h/CFCh。如果要写程序来访问配置空间,那么必须调用这组IO来实现。主要的形式为:

    out cf8h, config_address;
    in config_data,cfch;

    这里config_address表示函数需要输入的四个参数(BusNO, DeviceNO, FunctionNo, Register)来组合PCI总线的逻辑配置地址,以32bit表示。

    而config_data则是通过内部配置机制而得到的反馈数据,读到的就是PCI设备中的配置空间register,以32bit表示。

     

    PCI配置地址

    接下来大家都会关心如何组合得到config_address呢?config_address是32bit表示的,组合形式如下图所示。

    需要说明一下:

    Pci总线上最多支持256个bus;每个bus上最多支持挂载32个device;而每个device则最多支持7个function(关于function部分可以后续讨论);而PCI配置空间则最多有64个Register(32bit)。这些限制从上图也可以看出来的。

    所以一般以8bit来表示BusNO,5bit表示DeviceNO,3bit表示functionNO,6bit表示RegisterNO。

    在写入cf8h端口之前需要置bit31为‘1’。表示使能 pci总线配置周期,来实现访问pci设备的配置空间。

     

    PCI配置空间寄存器

    通过PCI总线的配置周期,得到的config_data是以什么形式表示的呢?

    其实,得到的32bit数据就是我们需要讨论的PCI配置空间。如下图:

    当然,得到的config_data是32bit表示的,实际情况PCI配置空间register可能是byte、word或者dword等。这个都不是问题。

     

     

    PCI配置空间的描述

    1、  PCI设备识别

    这些Register都是只读的,所有pci设备均要定义并使用这些register。程序也是通过读取这些register获得设备名称和厂商名称的。

    Vendor ID:     表示该设备的厂商代号。PCI SIG会给每个PCI设备厂商分配一个唯一的ID,16bit表示。如果读到该处为0ffffh,那么表示对应逻辑地址上没有设备存在。

    Device ID:     表示设备的ID号,这是由厂商自由分配的ID。

    Revision ID:  由厂商自己定义,可以认为是Device ID的扩展。

    Header type     区分设备类型的register。Bit7表示该设备是否是多fuction设备,若bit7=1表示为多功能设备(最大功能号位7),反之则是单功能设备。 而bit[6:0]则表示设备是否是bridge。00h表示普通pci设备,type0;如为01h,表示PCI bridge。

    Class code        这部分用来区分设备的功能性。包含三个byte。0Bh为base class code;0Ah为sub-class code;09h表示编程接口。对于base class code有如下定义:

    而sub-class code可以参考PCI spec的附录。往往,通过程序scan pci总线设备的时候,就是通过class code识别该设备的功能类型的。

     可以参考http://blog.csdn.net/pankul/article/details/8603632

     

    2、  PCI设备的控制Register

    Command:    通过此register来实现pci周期的响应,当0被写入此register时,设备逻辑上是不与总线”相连”的;而只有配置周期能访问该pci设备。如bit0、bit1均为0,则表示该设备对应的memory空间和io空间是不能访问的。上电启动该register为0.

     

    Bit Location

    Description

    0

    控制该设备对IO空间访问的响应。0表示不响应IO空间的访问;1表示能访问IO空间访问。

    1

    控制该设备对memory空间访问的响应。0表示不响应,1表示响应memory空间的访问。

    2

    控制该设备成为总线上的master。0表示不能产生Pci访问,1表示可以当做master来主动产生Pci 访问行为。

    3

    控制设备产生特殊的操作周期,具体不详。

    4

    控制设备能使用memory write and invalidate。该设备必须是master,才能产生memory write and invalidate 指令。详情参看pci spec 的chapter3

    5

    针对VGA设备来说的,enable VGA设备访问的palette 寄存器,并能侦测palette data。

    6

    使能设备响应parity errors

    7

    使能Wait周期,实现控制设备的address/data stepping。Stepping可以理解为单步?步进?

    8

    使能SEER#的驱动功能

    9

    针对master 设备来说的,在仲裁的问题中比较重要。置1表示支持到所有target的fast back-to-back 传输。

    Fast back-to-back表示在完成一个传输周期之后没有wait cycle,而是直接开始下一个数据传输。包括两个情况:对同一个target操作back2back;对不同的target操作back2back。由于pci总线是并行总线设计,所有的设备都是并联挂载在总线上,所有仲裁机制必须很好的处理好fast back2back问题。

    10-15

    Reserved

     

    3、  pci设备的状态Register

    无需多言,可以按照字面上来理解。

     

    4、  中断相关register

    Interrupt line:        8bit的register表示设备所分配的irq号。可读写的寄存器,在post阶段会被BIOS写入一个PCI irqrouting分配的中断。如果没有被使用则用‘FFh’表示。

    Interrupt Pin:         8bit的register表示设备使用的中断Pin脚。1-4分别表示INTA#、INTB#、INTC#、INTD#。这个是只读寄存器。

     

    5、  Base Address

    PCI设备一般都会需要分配memory空间或者IO空间。这些空间的基地址就保存在配置空间的BARx寄存器中。

    是否需要分配memory空间或者iO空间,这是由PCI设备自身属性来说的。看BAR的bit0的值。Bit0是只读位,0表示对应BAR对应于memory空间;1表示相应BAR对应于IO空间。如下图表示BAR适用于memory空间的基地址

     

    下图表示IO空间对应的基地址

    至于如何分配memory 、io空间,算法如何?这些可以后续再写出来。对于bios工程师来说最好的方式还是那句话:Read the fucking source code!

    这里只列举部分比较常用的PCI配置空间Register,其他的Register已经忽略,可以去详细阅读PCI spec。

    展开全文
  • linux下遍历访问PCIE设备配置空间

    千次阅读 2018-11-24 23:32:15
    linux下遍历访问PCIE设备配置空间PCIE 访问流程PCIE设备总线limitlinxu下怎么访问CONFIG_ADDRESS寄存器和CONFIG_DATA寄存器 PCIE 访问流程 通过bus号,device号,和function号访问到PCIE设备的信息,register号是...

    概述

    最近在看王齐老师编写的PCI Express体系结构导读,受益颇深,因此打算编程实现写小程序,加深对PCIE知识的理解。动手实践理解更深刻。
    本文章参考此博客: linux环境下遍历PCI设备,在此基础上实现了对PCIE 0x00~0x3f配置空间中的读取,打印输出基本和linux 自带lspci -x 命令形式一致。

    实验环境

    wimdow7系统,Intel 64位处理器
    VMware虚拟机 ubuntu14.04

    PCIE 访问流程

    HOST桥通过bus号,device号,和function号访问到PCIE设备的信息,register号是PCIE设备配置空间(PCIe设备配置空间4096KB)中寄存器的偏移。X86处理器这些信息存放在CONFIG_ADDR寄存器中,CONFIG_DATA寄存器保存该地址中的数据。因此可以通过读写这两个寄存器获取到PCIE设备配置空间中的信息,在X86处理器中这两个寄存器的地址为:
    ONFIG_ADDRESS地址是0xcf8,也就是说通过访问0xcf8就可以访问CONFIG_ADDRESS寄存器,
    CONFIG_DATA地址是0xcfc,CONFIG_DATA用来存放进行配置读写的数据。
    注意 X86处理器下CNFIG_ADDRESS的基地址0x80000000

    • CONGFIG_ADDRESS寄存器
      在这里插入图片描述

    bit31是使能对PCI Bus CONFIG_DATA的访问;

    bit 30~24为保留,为只读,访问时返回值为0;

    bit 23~16是Bus号;

    bit 15~10是设备号;

    bit 10~8是功能号;

    bit 7~2是配置空间中的寄存器,单位为DWORD。

    bit 1~0为只读,读取时放回为0。

    • PCIE设备配置空间
      在这里插入图片描述

    • PCIe 设备配置空间(0x00~0x03F)
      在这里插入图片描述

    PCIE总线资源

    • PCIE总线数量最大支持256个,每个pcie总线下设备最大支持32个,每个设备的功能最大支持8个
      #define MAX_BUS 256
      #define MAX_DEVIECE 32
      #define MAX_FUNCTION 8

    Linux下怎么访问CONFIG_ADDRESS寄存器和CONFIG_DATA寄存器

    • 涉及到的接口函数
    1. iopl() 改变当前进程的I/ O特权级别,在级别 level 指定,这一调用仅适用于i386平台。
      #include <sys/io.h>
      int iopl(int level);
      读写之前set high level 3
      读写完成之后set low level 0
    2. outl()
      outb() I/O 上写入 8 位数据 ( 1 字节 );
      outw() I/O 上写入 16 位数据 ( 2 字节 );
      outl () I/O 上写入 32 位数据 ( 4 字节)。
      #include <sys/io.h>
      void outb (unsigned char data, unsigned short port);
      void outw (unsigned short data, unsigned short port);
      void outl (unsigned long data, unsigned short port);
    3. inl()
      inl () I/O 上读出 32 位数据 ( 4 字节)。
      #include <sys/io.h>
      void inl (unsigned short port);

    注意 i386处理器 I/O 空间和内存空间的进程的 I/O 空间写入数据方式不同。Port I/O方式只能访问PCI配置空间,而不能访问PCI-E扩展配置空间(257~4096字节),此时只能通过MMIO方式。

    源代码

    #include <sys/io.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <stdlib.h>
    
    //define pcie device info limit
    #define MAX_BUS 256
    #define MAX_DEVICE 32
    #define MAX_FUNCTION 8
    //define CONFIG_ADDRESS and CONFIG_DATA
    #define CONFIG_ADDRESS 0xCF8
    #define CONFIG_DATA 0xCFC
    
    #define BASE_ADDR 0x80000000
    
    typedef unsigned int WORD;//4byte
    
    int main()
    {
        WORD bus,device,func,reg;
        WORD data,address;//read info from CONFIG_DATA,address set to CONFIG_ADDRESS
        int ret=0;
    	//unsigned char tmpc; 
        ret = iopl(3);
    	if(ret<0)
    	{
    		perror("iopl set to high level error\n");
    		return -1;
    	}
    	//printf("bus\tdev\func\n");
            for(bus=0;bus<MAX_BUS;bus++)
    		for(device=0;device<MAX_DEVICE;device++)
    			for(func=0;func<MAX_FUNCTION;func++)
    			{
    				for(reg=0;reg<16;reg++)
    				address = BASE_ADDR|(bus<<16)|(device<<11)|(func<<8);
    				outl(address,CONFIG_ADDRESS);//put addr to config_address
    				data = inl(CONFIG_DATA);//read data from config data;
    				if((data!=0xffffffff) && (data!=0))
    			 	{
    					printf("\n%02x:%02x:%02x\n",bus,device,func);
    					for(reg=0;reg<16;reg++)	
    					{
    						if(reg%4==0)	
    						{
    							printf("%02x:",reg*4);
    						}
    						address = BASE_ADDR|(bus<<16)|(device<<11)|(func<<8)|(reg<<2); 
    						outl(address,CONFIG_ADDRESS);//put addr to config_address
    						data = inl(CONFIG_DATA);//read data from config data;
    						printf("%02x ",(unsigned char)(data>>0));
    						printf("%02x ",(unsigned char)(data>>0));
    						printf("%02x ",(unsigned char)(data>>0));
    						printf("%02x ",(unsigned char)(data>>0));
    						if(reg%4==3)
    						printf("\n");
    					}
    					
    				}
    			}
    	iopl(0);
    	if(ret<0)
    	{
    		perror("iopl set to low level error\n");
    		return -1;
    	}
    	return 0;     
    }
    

    运行结果

    在这里插入图片描述

    展开全文
  • PCIe设备的配置空间

    千次阅读 2013-07-22 16:31:04
    关于PCI设备的配置空间网上已经有很多资料了,如下图就是PCI设备必须支持的64个字节的配置空间,范围为0x00-0x3f。配置空间" border="0" alt="PCIe 配置空间" src=...
  • PCI配置空间简介

    千次阅读 2013-02-03 17:21:47
    PCI有三个相互独立的物理地址空间:设备存储器地址空间、I/O地址空间和配置空间配置空间是PCI所特有的一个物理空间。由于PCI支持设备即插即用,所以PCI设备不占用固定的内存地址空间或I/O地址空间,而是由操作系统...
  • PCI配置空间

    千次阅读 2013-10-11 17:03:50
    PCI配置空间  最后编辑:2010-5-26(修改错别字) 一. 概括 任何计算机系统都会有输入/输出,所以对外部设备的访问是CPU设计中的一个重要问题。外设上一般会有很多寄存器,像状态寄存器、控制寄存器、数据...
  • PCI/PCIe基础——配置空间分布

    万次阅读 2018-07-12 13:59:57
    PCI配置空间由于PCI/PCIe设备分为Bridge和Agent两种,所以配置空间也有两种类型:其中Agent的配置空间类型称为Type 00h:简单介绍其中的几个寄存器的意义:Vendor ID,Device ID:标记了一个设备的生产厂商和具体的...
  • PCI设备的配置空间

    千次阅读 2013-10-21 12:06:42
    在一个具体的处理器应用中,PCI设备通常将PCI配置信息存放...读者可能会对这种机制产生一个疑问,如果系统软件在PCI设备将E2PROM中的信息读到配置空间之前,就开始操作配置空间,会不会带来问题?因为此时PCI设备的初始
  • PCIe扫盲——配置空间的读写机制

    千次阅读 2019-07-01 09:36:53
    需要特别注意的是,PCIe的Spec中明确规定只有Root有权限发起配置请求(Originate Configuration Requests),也就是说PCIe系统里面的其他设备是不允许去配置其他设备的配置空间的,即peer-to-peer的配置请求是不允许...
  • PCIe 基础(一)操作配置空间

    万次阅读 2016-07-17 10:25:57
    PCI配置空间PCI有三种地址空间:I/O空间,内存地址空间,PCI配置空间。在启动时bootloader 或者内核会遍历PCI总线并分配资源,如中断和内存,设备驱动程序通过PCI配置空间 找到资源分配。大小为256字节。 配置...
  • PCI配置空间的访问方式

    千次阅读 2013-03-15 14:45:42
    系统中的CPU是通过PCI设备的设备号以及配置空间中的寄存器编号来访问配置空间寄存器的 CPU通过产生PCI配置空间访问周期来访问PCI设备的配置空间,产生PCI配置空间访问周期的机制有以下两种。 n 机制1 通过CPU中...
  • PCIe扫盲——BDF与配置空间

    千次阅读 2019-07-01 09:35:28
    前面的文章中介绍过,每一个PCIe设备可以只有一个功能(Function),即Fun0。...不管这个PCIe设备拥有多少个功能,其每一个功能都有一个唯一独立的配置空间(Configuration Space)与之对应。 和PCI总线一样,...
  • PCI配置空间访问的细节

    千次阅读 2014-09-15 23:31:13
    PCI总线配置空间: 前段时间在看DM9000驱动的时候,瞄了一眼DM9000的datasheet。以前确实没有留意这种形式的
  • 如何访问pcie整个4k的配置空间

    千次阅读 2014-05-17 15:13:34
    目前用于访问PCIe配置空间寄存器的方法需要追溯到原始的PCI规范。为了发起PCI总线配置周期,Intel实现的PCI规范使用IO空间的CF8h和CFCh来分别作为索引和数据寄存器,这种方法可以访问所有PCI设备的255 bytes配置...
  • PCI设备读取配置空间

    千次阅读 2014-10-23 18:52:44
    PCI设备的配置信息包含了关于这个设备的基本情况的介绍,包括设备的名称,功能,使用方式等,因此首先必需要读取PCI设备的配置空间,才能够再讨论PCI设备的识别以及操作了。 PCI 规范系列文档总共定义了三种方法...
  • PCI配置空间(PCI Configuration Space)

    千次阅读 2018-11-09 16:03:01
    PCI设备(PCI device)都有一个配置空间,大小为256字节,实际上是一组连续的寄存器,位于设备上。其中头部64字节是PCI标准规定的,格式如下:     剩余的部分是PCI设备自定义的。 PCI配置空间头部有6个BAR...
  • Linux PCI/PCI-E设备配置空间读取与修改1 前言 PCI和PCI Express,是计算机常使用的一种高速总线。操作系统中的PCI/PCI-E设备驱动以及操作系统内核,都需要访问PCI及PCI-E配置空间。PCI/PCI-E设备的正常运行,离不...
  • PCI桥与PCI设备的配置空间

    千次阅读 2014-03-11 23:25:47
    PCI桥与PCI设备的配置空间   转载▼ PCI设备都有独立的配置空间,HOST主桥通过配置读写总线事务访问这段空间。PCI总线规定了三种类型的PCI配置空间,分别是PCI Agent设备使用的配置空间,PCI桥...
  • 基地址寄存器(BAR)在配置空间(Configuration Space)中的位置如下图所示: 其中Type0 Header最多有6个BAR,而Type1 Header最多有两个BAR。这就意味着,对于Endpoint来说,最多可以拥有6个不同的地址空间。但是...
  • PCIe配置空间和PCI设备中的寄存器

    千次阅读 2017-12-24 10:06:11
    1、访问PCI配置空间,PCI基本配置空间的读写使用下列函数: 原型定义在 int pci_read_config_byte(struct pci_dev *pdev, int where, u8 *val); int pci_read_config_word(struct pci_dev *pdev, int where, u8 ...
  • 访问PCIe配置空间using Intel Chipsets

    千次阅读 2013-01-20 23:36:58
    访问PCIe配置空间using Intel Chipsets    目前用于访问PCIe配置空间寄存器的方法需要追溯到原始的PCI规范。为了发起PCI总线配置周期,Intel实现的PCI规范使用IO空间的CF8h和CFCh来分别作为索引和数据寄存器,...
  • 4.3 PCIe设备的扩展配置空间

    千次阅读 2017-02-12 19:46:38
    本书在第2.3.2节讲述了PCI设备使用的基本配置空间。这个基本配置空间共由64个字节组成,其地址范围为0x00~0x3F,这64个字节是所有PCI设备必须支持的。事实上,许多PCI设备也仅支持这64个配置寄存器。 此外PCI/PCI-X...
  • PCI设备配置空间问题

    千次阅读 2011-03-23 14:54:00
    PCI设备配置空间问题  一般来讲,pci总线接口的实现有两种方法,一种是用可编程器件CPLD或FPGA,另一种方法是用专用的接口芯片,象PLX公司的PCI9054,CH365等。二者各有优缺点,使用可编程器件呢,可以...
  • PCI总线推出以来,以其独有的特性受到众多厂商的青睐,已经成为计算机扩展总线的主流。目前,国内的许多技术...一般软件编程人员基于对硬件设备原理的生疏,很难理解并操作配置空间,希望硬件开发人员直接告诉他们怎

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,115,786
精华内容 446,314
关键字:

配置空间