DW PCIE 的Register Module, LBC, and DBI章节学习笔记

SPIN互斥锁很好的链接

文章起源

PCIE的使用SPIN解决IP的LBC没有使用专用总线导致中断冲突问题的软件避归方案(特殊芯片使用)。后续再编写C语言的驱动程序时对IP的Register Module, LBC, and DBI章节进行一学习并记录学习理解和心得。

寄存器说明

Capability ID汇总
Capabilities结构说明
在初次看寄存器文档的时候比较容易迷糊。CAP 寄存器即对应功能的Capability(能力)说明,对应的地址都是B+0x** 容易让人迷糊。每个Resiters的描述内部都有个Capability指向下一个,每个CAP都有自己特定的ID号,对应固定的长度所以程序可以通过一个个的偏移量找到下个CAP从而完成全部的查找。
在这里插入图片描述

CAP的地址说明

PCI-X 和PCIe 总线规范要求其设备必须支持Capabilities 结构。在PCI 总线的基本配置空间中,包含一个Capabilities Pointer 寄存器,该寄存器存放Capabilities 结构链表的头指针。在一个PCIe 设备中,可能含有多个Capability 结构,这些寄存器组成一个链表,如下图所示。

其中每一个Capability 结构都有唯一的ID 号,每一个Capability 寄存器都有一个指针,这个指针指向下一个Capability 结构,从而组成一个单向链表结构,这个链表的最后一个Capability 结构的指针为0。链表开始的指针地址为0x34处的1byte数值,寻址过程如下。注意对应的偏移地址是绝对地址,不是从本身CAP计算的偏移地址。

相关说明链接

在这里插入图片描述
在这里插入图片描述
比如下面的读取 0X34->0X40(bit8-16)->0X50(bit8-16)->0X70(bit8-16)->0XD0(bit8-16) 在0XD0 对应下一个CAP地址为0,在这结束了CAP.

 [0000] abcd16c3 00100107 06040001 00010000
 [0010] 00000000 00000000 00ff0100 20000000
 [0020] 00000000 00010001 00000000 00000000
 [0030] 00000000 00000040 00000000 000001ff
 [0040] 5bc35001 00000008 00000000 00000000
 [0050] 038a7005 00000000 00000000 00000000
 [0060] 00000000 00000000 00000000 00000000
 [0070] 0042d010 00008021 00002110 00534842
 [0080] 30420000 0006007f 004003c0 00000000
 [0090] 00000000 80000410 00000000 80000006
 [00a0] 40000002 00000000 00000000 00000000
 [00b0] 00000000 00000000 00000000 00000000
 [00c0] 00000000 00000000 00000000 00000000
 [00d0] 00000003 00000000 00000000 00000000
 [00e0] 00000000 00000000 00000000 00000000
 [00f0] 00000000 00000000 00000000 00000000

我使用的芯片当切换到访问RC本身寄存器的时候对应地址列表:
F9000034 :00000040 所属内容 PF0_TYPE1_HDR :NEXT=0X40
F9000040 :5bc35001 所属内容 PF0_PM_CAP ID=0X01 NEXT=0X50
F9000050 :038a7005 所属内容 PCI_MSI_CAP_ID_NEXT_CTRL ID=0X05 NEXT=0X70
F9000070 :0042d010 所属内容 PF0_PCIE_CAP ID=0X10 NEXT=0Xd0
F90000d0 :00000003 所属内容 /PF0_MSI_CAP ID=0X3 NEXT=0X0 (最后一个CAP)

几个定义

DSP:RC Mode 对应的模式
USP:EP Mode 对应的模式

CDM:Configuration Dependent Module.This is an internal block in the native controller that has the PCIe configuration registers and some user-accessible registers.包括 PICE叫做的配置寄存器(比如PCIE 从机显示的标准设置头信息)和 厂家定义的寄存器(比如ATU和DMA等)。

ELBI:External Local Bus Interface.Delivers an inbound register RD/WR received by the controller to external application registers when the controller is expected to generate the PCIe completion of this register
RD/WR. For switch applications: the ELBI is intended for incoming requests that are targeted to local switch application registers, while TRGT1 is intended for TLPs that are passing through the switch. The controller automatically generates completions for requests that are routed to the ELBI。ELBI和CDM 注册了本地寄存器,在下面章节寄存器配置空间概览有描述。ELBI我理解为通过PCIE访问一个CPU的内部空间寄存器。ELBI 主要是在EP端,使用RC没有该部分功能。

LBC:Local Bus Controller .This is an internal block that allows the DBI interface (from your application side), or the wire side interface (through the TRGT0 interface), to access the CDM or your external application registers on the ELBI.本地的寄存器控制,比如RC中断清除等相关都需要操作。

XALI:Transmit Client Interface.理解为给外部传输的接口

DBI:Data Bus Interface.You can use this interface to locally access the controller’s internal registers in the CDM, or your external application registers on the ELBI. You can optionally connect a local CPU or controller to this port.

CQ 和CC :PCIe 完成器请求 (CQ)/完成器完成 (CC) 模块用于从远程 PCIe 代理接收 TLP 请求并加以处理。

DBI 内部划分

DBI内部划分了2个部分,DBI和DBI2通过片选来进行选择。
When you are using an AXI DBI slave, shadow registers can only be accessed through the DBI where you select between the two registers using the CS2 address bit.This is called DBI2, CS2, dbi_cs2, DBI_CS2, or Dbi2 access; all of these terms mean the same thing.

DBI2和DBI内容具体区别看本文“寄存器配置空间概览”部分章节

我使用芯片的空间排布

我使用的芯片DBI和DBI2的地址关系是pci->dbi_base2 = pci->dbi_base + 0x100000。
DBI: 0
DBI2: 0x100000
iATU: 0x300000
DMA: 0x380000
在这里插入图片描述

问题原因

设计使用IP时没有使用独立Native的一条CPU直接访问LBC访问寄存器的总线通道DBI(见Local Bus Controller (LBC)章节和Data Bus Interface (DBI) Access章节)。在设置EP端和RC自身LBC访问通道只能用同一个通道AXI 的SLAVE通道。
AXI DBI 访问使用的是 Shared Slave Interface 模式,即共享总线访问方式。CPU作RC主模式时对内部的LBC控制寄存器的访问和对外部EP设备的寄存器访问使用的是同一套总线,并没有使用专用的DBI总线。如下图1 访问XALI外部和访问内部LBC是通过SWITCH 来控制切换的。在没有中断的情况下该不会有访问冲突,但是在使用SMI中断的情况下由于中断和EP设备驱动可能不运行在多核的同一个CPU上会导致中断中切换到LBC路径访问时,EP设备驱动如果同时在访问XALI实际设备驱动访问的时LBC,导致EP设备驱动读取数据异常。
所以使用时需要对RC模式下的驱动进行修改,保证中断访问PCI寄存器和应用访问EP互斥,防止同时使用到AXI SLAVE。

CPU能直接DBI访问
AXI DBI Access with a Dedicated Slave Interface SHARED_DBI_ENABLED =0, DBI_4SLAVE_POPULATED =1)
在这里插入图片描述

我们芯片的处理方式
AXI DBI Access with a Shared Slave Interface (SHARED_DBI_ENABLED =1, DBI_4SLAVE_POPULATED =0)
SWITCH 切换访问自身的寄存器或是EP的寄存器

我们芯片的设置切换代码如下,是通过设置PCIE的SIDEBAND的2个寄存器来影响切换,保证从AXI接口访问访问到LBC

static void pcie_sideband_dbi_disable(struct oa1801_pcie *oa1801_pcie)
{
	u32 val = 0;

	val = oa1801_sideband_readl(oa1801_pcie, SIDEBAND_SLV_AWMISC_INFO);
	val &= (~AXI_DBI_W_EN);
	oa1801_sideband_writel(oa1801_pcie, val, SIDEBAND_SLV_AWMISC_INFO);

	val = oa1801_sideband_readl(oa1801_pcie, SIDEBAND_AXI_DBI_R_EN_INFO);
	val &= (~AXI_DBI_R_EN);
	oa1801_sideband_writel(oa1801_pcie, val, SIDEBAND_AXI_DBI_R_EN_INFO);
}

static void pcie_sideband_dbi_enable(struct oa1801_pcie *oa1801_pcie)
{
	u32 val = 0;

	val = oa1801_sideband_readl(oa1801_pcie, SIDEBAND_SLV_AWMISC_INFO);
	val |= AXI_DBI_W_EN;
	oa1801_sideband_writel(oa1801_pcie, val, SIDEBAND_SLV_AWMISC_INFO);

	val = oa1801_sideband_readl(oa1801_pcie, SIDEBAND_AXI_DBI_R_EN_INFO);
	val |= AXI_DBI_R_EN;
	oa1801_sideband_writel(oa1801_pcie, val, SIDEBAND_AXI_DBI_R_EN_INFO);
}

寄存器配置空间概览

The controller has 4096 bytes of register space per function. Based on the location of the registers, this space is divided into two groups, CDM and ELBI. PICE控制器的4096字节空间用于作为寄存器控制,这个空间又分为两部分一部分为CMD空间一部分为ELBI空间。
CDM:前面名词解释有说明,包括了一些PCI 配置头部信息,PCIE设备本身标准或者是扩展的功能和端口的逻辑寄存器。对于PCI使用来说我的理解就是我们使用命令PCI -vvvv 能看到的东西。

ELBI:
通过外部接口(PCIE)访问寄存器是通过ELBI 进行的。

对于PCIE 的EP和RC 他们的排布是有一定差异的。右边的CS2=0和CS2=0有不同的访问区域,如果是设置CDM/ELBI 为1 的情况,访问的是特殊的寄存器Shadow(比较特殊的寄存器,算是IP厂家特殊的);

Shadow Registers:PCI头部的一些设置是在Shadow寄存器中设置,比如BAR的MASK,前面介绍是在DBI2地址范围。

EP 的排布:
1.右边是DBI2访问的空间内容。
2.左边是DBI访问空间内容。
在这里插入图片描述

RC对应空间排布:

在这里插入图片描述
UPS即EP模式下恩不CFG访问和外部MEM和IO访问对应的空间关系。
在这里插入图片描述

对应上面图左边UPS即EP模式下 DBI访问空间地址说明

在这里插入图片描述

需要注意的地方

VIEWPORT功能说明

实际发现ATU可以使用直接访问的方式也可以使用VIEWPORT 的方式,直接访问方式地址为0x300000起始地址,使用VIEWPORT在LINUX驱动中被定义为0X900开始。
VIEWPORT 方式说明:
置地址在CS2=0的情况下。直接访问比如AUT 第N个iATU Region Control 1 Register.为:0x700+0x200*(N+1)。间接访问就首先配置 700+200地址的 (iATU_VIEWPORT_OFF)寄存器,设置访问第N个iATU。然后iATU Region Control 1 Register.为:0x700+0x200+0x4

置地址在CS2=0的情况下。直接访问比如AUT 第N个iATU Region Control 1 Register.为:0x700+0x200*(N+1)。间接访问就首先配置 700+200地址的 (iATU_VIEWPORT_OFF)寄存器,设置访问第N个iATU。然后iATU Region Control 1 Register.为:0x700+0x200+0x4。
程序设置(iATU_VIEWPORT_OFF)寄存器如下:
dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, PCIE_ATU_REGION_INBOUND | index);

CPU AXI桥访问DBI AXI Bridge DBI Access

在这里插入图片描述
在LINUX 驱动下可以看到DMA 和ATU 后缀加unroll参数的部分程序。在头文件也有介绍

/*
 * iATU Unroll-specific register definitions
 * From 4.80 core version the address translation will be made by unroll
 */
#define PCIE_ATU_UNR_REGION_CTRL1	0x00
#define PCIE_ATU_UNR_REGION_CTRL2	0x04
#define PCIE_ATU_UNR_LOWER_BASE		0x08
#define PCIE_ATU_UNR_UPPER_BASE		0x0C
#define PCIE_ATU_UNR_LIMIT		0x10
#define PCIE_ATU_UNR_LOWER_TARGET	0x14
#define PCIE_ATU_UNR_UPPER_TARGET	0x18

地址访问设置方式如下:

/* Register address builder */
#define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region)	\
			((0x3 << 20) | ((region) << 9))

#define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region)				\
			((0x3 << 20) | ((region) << 9) | (0x1 << 8))

static u32 dw_pcie_readl_ob_unroll(struct dw_pcie *pci, u32 index, u32 reg)
{
	u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);

	return dw_pcie_readl_dbi(pci, offset + reg);
}

static void dw_pcie_writel_ob_unroll(struct dw_pcie *pci, u32 index, u32 reg,
				     u32 val)
{
	u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);

	dw_pcie_writel_dbi(pci, offset + reg, val);
}

我使用的CPU就是通过unroll模式对ATU 、DMA 进行访问。对应地址设置如图

在这里插入图片描述
在这里插入图片描述

ELBI和外部总线

关于访问的数据流实线是访问CDM,虚线为访问ELBI。
PCIe Wire Access to CDM Registers or ELBI:
在这里插入图片描述
DBI Access to CDM Registers or ELBI:
其中实线是DBI 接口访问CMD.
在这里插入图片描述

BAR 的详解

EP 模式下的BAR

常规的BAR介绍我简单说一下,不清楚的看文档和上网了解。

  1. 32BIT 64BIT 访问
  2. 设置BAR地址和BAR大小(通过BAR MASK)
  3. 通过写BAR的MASK为0禁止BAR
  4. 可设置IO、MEM、预取等特性
  5. 通过BAR可以访问TRGT1 (AXI master interface), TRGT0 ( access internal port logic registers or external application registers on the ELBI)

BAR MASK的配置注意事项

Memory BAR Sizes:开启了MEM BAR 对应的[11:0]设置为1,因为2.0PCIE要求是4KB最小值。
IO BAR Sizes:开启IO BAR 为256个最小值。
BAR Mask Registers访问方式:EP是通过DBI接口对寄存器访问,该地址和BAR地址寄存器一样。不过通过DBI总线访是通过CS2切换访问的shadow访问得到的是MASK寄存器。

RC 模式下的BAR

RC存在两个 BAR,但预计不会使用。 您应该禁用它们以避免在设备枚举期间进行不必要的内存分配。 如果您确实使用 BAR,那么您应该对其进行编程以捕获针对本地非应用程序内存空间的 TLP定义在 TRGT1 (AXI master interface), 不适用于 TRGT1 上的应用程序(Because in a DSP, there is no wire access to TRGT0 (ELBI or CDM) using CFG requests or BAR-matched MEM requests.). BAR 范围必须在三个范围之外基础/限制区域(Base/Limit regions)

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值