PCIe架构定义了4种地址空间:配置空间、Memory空间、IO空间和message空间。
每个PCIe Function都有4KB的配置空间(Configuration Space)。前256 Bytes是和PCI兼容的配置空间,剩余的是PCIe扩展配置空间(Extended Configuration Space)。PCIe配置空间如下图所示,地址范围为0x000~0xfff。
软件可以通过配置空间来对设备的状态进行控制和检查。PCI兼容的配置空间可以通过CAM或者ECAM机制来访问,而PCIe扩展配置空间只能通过ECAM机制来访问。
PCIe Enhanced Configuration Access Mechanism (ECAM)是访问PCIe配置空间的一种机制。是将PCIe的配置空间映射到MEM空间,使用MEM访问其配置空间的一种实现。
PCI兼容的配置空间Header如下图,大小是64B,分为Type0和Type1。Type 0有6个BAR(每个大小为32bit),Type 1有2个BAR。Type 1 Header存在于所有Bridge设备中,即每个Switch和RC都有1个Type 1 Header。Type 0 Header只存在于非Bridge设备中,即Endpoint设备。
PCIe支持I/O空间,以便与需要使用I/O空间的传统设备(legacy device)兼容,即PCI或PCI-x设备。IO地址空间的大小只有4GB(32-bit)。PCIe spec并不推荐使用I/O空间,推荐使用内存空间映射(MMIO)。
访问memory的地址空间,即mmio空间,对于32位操作系统来说是4G(2^32),对于64位系统来说,有2^64的空间大小。
此mmio空间和main memory(内存或者主存)是两个概念。MMIO,即Memory Mapped IO,就是把这些IO设备中的内部存储和寄存器都映射到统一的存储地址空间(Memory Address Space)中。
下图是一种通用的memory和IO的映射。PCIe支持的memory地址最多为64bit。图中仅展示了EP所使用的MMIO和IO,但是这种能力并不是EP所独有的。Switch和RC内部也存在着可以通过MMIO和IO地址来进行访问的设备特定寄存器。
图4‑1展示了两种不同类型的MMIO:可预取MMIO(Prefetchable MMIO,P-MMIO)和不可预取MMIO(Non-Prefetchable MMIO,NP-MMIO)。可预取空间有两个属性:
X86采用独立编址的方式,将memory操作与外设IO操作分开了,才有了memory空间和IO空间的区分。ARM采用统一编码的方式。
BAR空间示例 -- 32bit内存地址空间请求
接下来介绍一个获取4KB大小的不可预取MMIO的例子。首先看一下PCIe spec中对BAR寄存器的描述:bit 0指示是Memory空间还是I/O空间,bit[2:1]指示是32-bit映射还是64-bit映射,bit 3表示是否支持预取,为1表示支持预取。bit[3:0]是只读的。当采用64-bit映射时,需要使用2个BAR来定义基地址。
具体过程如下图(1)、(2)、(3)所示:
(1) 表示BAR未初始化的状态,设计者将低bit[11:0]固定为一个数值,属性只读(RO),用来指示需要的memory大小和类型,高位bit(属性RW)用X来表示,即它们的值还未知。
(2) 软件(OS)把每个BAR都通过配置写操作将可写入的bit写为全1(被固定的低位bit不受影响)。除了bit[11:0]以外,所有的bit都被写为1。写全1是为了确定最低位的可写入的bit是哪一位,这个bit的位置指示了请求的地址空间大小。在本例中,最低位可写入的bit为bit 12,因此这个BAR需要请求2^12(4KB)的地址空间。如果最低可写入bit为bit 20,那么就要请求2^20(1MB)的地址空间。
然后软件从BAR0开始,依次读取每个BAR的数值,从而确定各个BAR要请求的地址空间的大小和类型。
(3) 软件通过将起始地址写入BAR0来为BAR0分配一个地址范围。在本例中,这个起始地址为F900_0000h。
至此,对BAR0的配置就完成了。一旦软件使能了命令寄存器(Command register,偏移地址04h)中的Memory Space Enable bit,那么这个设备就会接受地址在F900_0000h-F900_0FFFh(4KB大小)范围的memory请求。
上个例子是通过BAR0来请求32-bit的不可预取的MMIO空间。本例介绍通过BAR1和BAR2来请求一块64-bit的可预取MMIO空间(64MB大小)。由于地址是64-bit,因此必须将两个连续相连的BAR一起使用。
跟上个例子一样,将BAR配置过程分为3个节点:
(1) BAR1和BAR2都处于未初始化的状态。设计者将低位BAR(本例中为BAR1)中的低bit固定为一个数值,指示需要的memory大小和类型,高位BAR(BAR2)中的bit则都是可读可写的,没有被固定。
(2) 软件把每个BAR都通过配置写操作将可写入的bit写为全1。除了BAR1中被固定的低位bit以外,所有的bit都被写为1。
软件读取BAR0后,读取下一个BAR(BAR1)来确定设备是否在请求更多的地址空间。一旦BAR1被读取,软件发现设备在请求更多的地址空间,并且是64-bit的可预取MMIO空间。因此软件会读取BAR2,但并不会对BAR2进行低bit的评估,因为软件仅仅是将BAR2当做BAR1发起的64-bit地址请求的高32-bit。
(3) 软件为这一对BAR分配地址范围。软件通过两次配置写操作将64-bit起始地址写入BAR1与BAR2。在本例中,高位BAR的bit 1(BAR pair的bit 33)被置为1,低位BAR的bit 30(BAR pair的bit 30)也被置为1,这表示地址是2_4000_0000h。两个BAR中所有其他可写bit都被清零。
至此,BAR1和BAR2的配置就完成了。一旦软件使能了命令寄存器(Command register,偏移地址04h)中的Memory Space Enable bit,那么设备就会接受所有地址在2_4000_0000h-2_43FF_FFFFh(64MB大小)范围的memory请求。
message空间用来report带内的message和event。例如error message、电源管理消息等。
到目前为止,I2C、SPI 和 UART 等仍然是电子嵌入式设备中最常用的通信协议,本文,我们将剖析这三种协议,让大家清楚、直观的了解它们的功能、优点和局限性,并辅以 GIF 动图展示。
固态硬盘(SSD)已经成为数据存储的重要部分,其高速性能和稳定性让它广泛应用于各类计算设备中。SSD 固态硬盘的接口类型是决定其性能的关键因素之一。本文将深入探讨 SSD 固态硬盘的各种接口类型,助你更好地了解和选择适合你需求的SSD产品。
U盘是一种广泛使用的可移动存储设备,用于便捷地在计算机之间传输文件。
然而,即使您经常使用U盘,这些冷知识你可能还真不知道,一起来看看吧。
本文整理了一些关于隔离I2C设计的FAQ,供您参考。这些见解是根据德州仪器在线支持社区中有关I2C隔离器的常见问题而提供的。希望这些信息能够帮助工程师在设计过程中解决信号和电源隔离的问题。
© 2024 VxWorks Club