PCI驱动与AXI总线框架解析(RK3399)

往期内容

本文章相关专栏往期内容,PCI/PCIe子系统专栏:

  1. 嵌入式系统的内存访问和总线通信机制解析、PCI/PCIe引入
  2. 深入解析非桥PCI设备的访问和配置方法
  3. PCI桥设备的访问方法、软件角度讲解PCIe设备的硬件结构
  4. 深入解析PCIe设备事务层与配置过程
  5. PCIe的三种路由方式

Uart子系统专栏:

  1. 专栏地址:Uart子系统
  2. Linux内核早期打印机制与RS485通信技术
    – 末片,有专栏内容观看顺序

interrupt子系统专栏:

  1. 专栏地址:interrupt子系统
  2. Linux 链式与层级中断控制器讲解:原理与驱动开发
    – 末片,有专栏内容观看顺序

pinctrl和gpio子系统专栏:

  1. 专栏地址:pinctrl和gpio子系统

  2. 编写虚拟的GPIO控制器的驱动程序:和pinctrl的交互使用

    – 末片,有专栏内容观看顺序

input子系统专栏:

  1. 专栏地址:input子系统
  2. input角度:I2C触摸屏驱动分析和编写一个简单的I2C驱动程序
    – 末片,有专栏内容观看顺序

I2C子系统专栏:

  1. 专栏地址:IIC子系统
  2. 具体芯片的IIC控制器驱动程序分析:i2c-imx.c-优快云博客
    – 末篇,有专栏内容观看顺序

总线和设备树专栏:

  1. 专栏地址:总线和设备树
  2. 设备树与 Linux 内核设备驱动模型的整合-优快云博客
    – 末篇,有专栏内容观看顺序

img

1.PCI驱动程序框架

1.1 PCI驱动框架

img

在bus平台总线中,都知道Dev硬件设备树资源可以通过在设备树指定然后被内核读取存储进为platform_device中,也可以在.c文件中去指定好设备的资源让虚拟的总线平台去读取,这些都基于我们提前知道了设备的硬件资源。

但是对于真实的PCI设备,它的资源哪里的?我们比较难去知道接入在板子上的PCI设备是什么,显卡?声卡?网卡?因此需要去扫描接入在PCI接口上的PCI设备去读取到它的硬件资源。

img

对于PCI_Host和PCIe设备都有自己的驱动

  1. 首先针对PCI_Host(RC),RC的硬件设备资源可以通过在设备树中去进行指定,采用的虚拟的总线平台,当资源和驱动程序匹配后,会调用的RC驱动程序中的probe函数,probe函数会去识别扫描挂在PCIe/PCI接口上PCI设备,创建出一个pci_dev来指代设备,里面有其资源,这个pci_dev会被挂载PCI主桥上
  2. 而对于PCI设备,既然被识别到了获取到了信息,它也有自己的驱动,也就是pci_driver。 两者(pci_driver和pci_dev)类似RC(device和driver)挂在虚拟platform平台总线那样被挂在了RC下的总线平台上 。当pci_driver和pci_dev匹配后,同样也会去调用自己的probe函数,比如可以去初始化本身。

下面是更详细的流程介绍:

1. PCI Host (Root Complex, RC) 的驱动流程

a. 设备树描述

  • 在嵌入式系统中,PCI Host的硬件资源通过设备树(Device Tree, DT)来描述。设备树中会指定PCI控制器(RC)的资源,如内存映射地址、IRQ信息、时钟等。

b. Platform总线

  • PCI Host(RC)的驱动通常是基于平台设备(platform device)的,属于虚拟总线平台架构。设备树中的硬件信息会通过平台设备的框架传递给RC驱动
  • 当资源匹配成功后,平台驱动框架会调用RC驱动中的probe函数。

c. RC驱动中的probe函数

  • probe函数负责初始化Root Complex,并启动总线扫描。它会扫描连接到PCIe接口的所有设备,识别出挂载在RC下的PCIe/PCI设备。
  • 扫描过程会通过读取配置空间中的设备ID、功能号等信息,发现并初始化每一个设备。
  • 对于每个扫描到的设备,会创建一个对应的pci_dev结构体,这个结构体包含了该设备的所有硬件资源、配置信息,以及挂载的父总线信息。
  • pci_dev最终会挂载到PCI主桥上(即RC),形成PCI设备拓扑树。

2. PCIe设备的驱动流程

a. PCIe设备被识别

  • 一旦PCI Host完成设备扫描,每个设备的配置信息(如Vendor ID, Device ID, Class Code等)就会存储在相应的pci_dev结构体中。
  • 这些信息可以用来匹配相应的设备驱动程序,即pci_driver

b. PCIe设备的驱动(pci_driver)

  • PCI设备有自己的pci_driver驱动程序。这个驱动程序通过Vendor ID、Device ID或Class Code与pci_dev进行匹配。
  • 类似于platform设备的驱动匹配机制,PCI设备的驱动也是通过PCI核心层自动匹配pci_devpci_driver

c. pci_driver中的probe函数

  • pci_devpci_driver匹配成功后,PCI核心层会调用该PCI设备驱动中的probe函数。
  • probe函数用于初始化设备,设置DMA,分配IO内存,配置寄存器等。该函数会利用pci_dev结构体中的资源来完成这些初始化操作。

d. 设备初始化

  • probe函数中,驱动程序通常会:

    • 读取和配置设备寄存器。
    • 设置中断处理。
    • 启动设备的DMA或内存映射。
    • 启动设备的I/O功能,使设备可以正常工作。

3. PCIe设备和RC的交互

  • 在整个过程中,PCI设备是挂载在RC下的。在设备被成功识别、匹配驱动并初始化后,它就可以通过RC访问主内存、发送和接收数据包。RC管理了所有PCI设备的地址映射和中断请求,确保各个设备的正常通信。

RC驱动通过设备树和平台总线平台架构来初始化,并通过扫描设备生成pci_dev

PCIe设备驱动(pci_driver)通过匹配pci_dev,调用probe函数对设备进行初始化,使设备可以正常工作并与RC通信。

1.2 回顾一下地址空间的配置

img

在PCI/PCIe设备的扫描和初始化过程中,设备申请的空间范围的基地址(Base Address Register, BAR)会在设备的配置过程中进行读取和写入。这个过程发生在PCIe总线扫描时,特别是在PCIe配置空间的初始化阶段

1. PCIe总线扫描过程

  • 在Root Complex (RC) 驱动的probe函数中,PCIe主桥会扫描总线上连接的所有设备。
  • 每个设备都拥有一块标准的PCIe配置空间,其中包含了设备的Vendor IDDevice IDClass CodeBARs等信息。扫描时,RC会通过配置事务读取每个设备的配置空间。

2. 读取和写入基地址寄存器(BAR)

  • 每个PCIe设备的配置空间中包含几个基地址寄存器(Base Address Registers, BARs),这些寄存器用于告诉系统设备需要映射的内存空间或I/O地址空间的大小和位置。
  • BAR寄存器是32位或64位的寄存器,用于指定设备的内存或I/O空间基地址。

3. 基地址的申请和写入

  • 在扫描阶段,RC驱动会执行以下操作:

    1. 读取BAR寄存器的内容:初始时,驱动程序会读取设备的BAR寄存器来确定设备需要的地址空间大小。具体操作是写入0xFFFFFFFF到BAR中,然后读取BAR的值,从中可以得出设备所需的地址空间大小。
    2. 分配地址空间:根据设备的需求,RC会分配适当的物理地址范围(内存或I/O空间),以确保设备的地址空间不会与其他设备冲突。
    3. 写入BAR寄存器:RC驱动会将分配好的地址范围写入设备的BAR寄存器,从而为该设备分配实际的内存或I/O地址空间。

4. 完成设备初始化

  • 通过写入BAR寄存器,设备的内存或I/O空间被映射到系统的地址空间中,操作系统或驱动程序可以通过这些地址访问设备的资源。
  • 这一步完成后,设备的资源就已经可以正常使用,pci_dev结构体也会被初始化,包含设备的配置信息和资源描述。

扫描过程中会涉及设备申请空间范围的基地址的写入。这个过程是通过读取和写入BAR寄存器来完成的,用以分配和映射设备所需的内存或I/O空间。

2.RK3399_PCIe芯片手册解读之AXI总线

AXI相关:\协议\AXI\ug1037-vivado-axi-reference-guide.pdf

开发板资料:\芯片手册\RK3399 Rockchip RK3399TRM V1.3 Part2.pdf

2.1 连接情况

img

实际芯片中,CPU与外设之间的连接更加复杂,高速设备之间通过AXI总线连接。AXI总线总传输数据的双方分为Master和Slave,Master发起传输,Slave回应传输。Master和Slave是多对多的关系,它们之间读、写可以同时进行的,内部结构图如下:

img

实际系统中,CPU(作为AXI总线的Master)可以发起读写操作,而PCI控制器则通常作为Slave连接在AXI总线上,处理来自CPU或其他Master的请求,并通过PCI/PCIe总线与下游设备通信。这个结构允许CPU通过AXI总线间接与PCIe设备进行通信。

在实际系统中的连接:

  1. CPU和PCI控制器的关系
    CPU 作为 Master 发起对 PCIe 控制器(Host Bridge/RC)的访问。PCIe控制器作为 Slave 响应这些访问请求。通过 AXI 总线,CPU 会向 PCIe 控制器发送请求,然后控制器对接收到的请求进行翻译,最终传输到PCIe设备。
  2. AXI 总线结构
    上图可以看到典型的 AXI 总线连接结构。多个 Master 设备(如 CPU、DMA 控制器等)可以通过 Crossbar 连接到多个 Slave 设备(如 PCIe 控制器、存储设备等)。数据的传输是通过 AXI 总线上的多个信号通道完成的。对于读写操作,Master 设备发送地址和控制信号,Slave 设备接收请求并回应数据。
  3. PCI 控制器(RC/Host Bridge)下的 PCIe 设备
    PCIe 控制器(RC)管理下游设备。它将来自 AXI 总线的请求转化为 PCIe 总线标准,并与下游 PCIe 设备交互。在 PCIe 设备的配置过程中,CPU 会通过 AXI 总线发起配置请求,PCIe 控制器解析并转发到目标设备。此时,设备会返回其 BAR(Base Address Register)信息,确定内存映射地址空间。

因此,简而言之,CPU 是 Master,PCIe 控制器是 Slave。这种架构使得 CPU 可以通过 AXI 总线间接访问挂载在 PCIe 控制器下的设备。

2.2 PCI控制器

RK3399的PCIe控制器就是挂在AXI总线上,在RK3399芯片手册中可以看到:

  • AWADDR:AXI总线的写地址通道地址线,简单理解就是CPU要写PCIe控制器时发出的地址线
  • ARADDR :AXI总线的读地址通道地址线,简单理解就是CPU要读PCIe控制器时发出的地址线

img

2.3 五个通道

在AXI总线中,读写可以同时进行,有5个通道:

  • 读:

    • 读地址通道:传输读操作的地址
    • 读数据通道:传输读到的数据
  • 写:

    • 写地址通道:传输写操作的地址
    • 写数据通道:传输要写的数据
    • 写响应通道:传输写操作的结果

img

img

通道名称通道功能数据流向
read address读地址通道主机->从机
read data读数据通道(包括数据通道和读响应通道)从机->主机
write address写地址通道主机->从机
write data写数据通道主机->从机
write response写响应通道从机->主机

2.4 信号线

AXI总线和其他总线一样,具有很多的信号,其中包括全局信号、写地址通道信号、写数据通道信号、写响应通道信号、读地址通道信号、读数据通道信号、低功耗接口信号。丰富的信号集分布在不同的通道中,每个通道都负责特定的功能,以实现高效的数据传输。

信号AXI4AXI4-Lite
AWADDR写地址通道:地址线,最多可达64位写地址通道:地址线,最多可达64位
WDATA写数据通道:数据线,32~1024位写数据通道:数据线,32位
ARADDR读地址通道:地址线,最多可达64位读地址通道:地址线,最多可达64位
RDATA读数据通道:数据线,32~1024位写数据通道:数据线,32位

AXI总线(AXI4 和 AXI4-Lite)拥有丰富的信号集,分布在不同的通道中,每个通道都负责特定的功能,以实现高效的数据传输。下面列出了除你提到的 AWADDR(写地址通道)、WDATA(写数据通道)、ARADDR(读地址通道)、RDATA(读数据通道)以外的其他重要信号,并按照通道划分。下面是除了上面信号的其它信号,按照通道划分:

1. 全局信号

这些信号在AXI协议中是全局信号,负责时钟和复位管理:

  • ACLK:时钟信号,所有的 AXI 信号都基于这个时钟。
  • ARESETn:复位信号,低电平有效。用于系统复位。

2. 写地址通道信号

写地址通道用于发送写操作的地址和控制信息:

  • AWVALID:写地址有效信号,表示地址传输有效。当 Master 准备好写地址时,将其置为高。
  • AWREADY:写地址就绪信号,表示 Slave 准备好接收写地址。为高时,Slave 可以接受地址。
  • AWID(可选,AXI4 独有):标识 ID,用于区分不同的写事务。
  • AWLEN:突发长度,指定突发传输中传输的数据数量。
  • AWSIZE:突发传输的宽度,表示每次突发传输的数据大小(如字节、半字、字等)。
  • AWBURST:突发类型,定义突发传输是固定地址、递增地址还是包装突发。
  • AWLOCK:锁信号,表示是否需要独占访问资源。
  • AWCACHE:缓存类型信号,指示访问类型(缓存、缓冲等)。
  • AWPROT:保护类型信号,用于定义访问的权限和安全属性。
  • AWQOS:服务质量信号,用于指示 QoS(服务质量)等级。

3. 写数据通道信号

写数据通道用于传输写操作的数据:

  • WVALID:写数据有效信号,表示数据传输有效。当 Master 准备好写数据时,将其置为高。
  • WREADY:写数据就绪信号,表示 Slave 准备好接收写数据。为高时,Slave 可以接收数据。
  • WSTRB:写选通(Byte strobe),用于标识哪个字节有效。每一位对应一个数据字节的有效性(1 表示有效)。
  • WLAST:突发传输中的最后一个数据信号。Master 通过该信号告知 Slave 突发结束。

4. 写响应通道信号

写响应通道用于向 Master 返回写操作的响应:

  • BVALID:写响应有效信号,表示写响应有效。Slave 通过该信号告知 Master 写操作完成。
  • BREADY:写响应就绪信号,表示 Master 准备好接收写响应。
  • BID(可选,AXI4 独有):写响应 ID,用于与 AWID 匹配,确保写响应对应正确的事务。
  • BRESP:写响应,表示写操作的状态(如 OKAY、EXOKAY、SLVERR 或 DECERR)。

5. 读地址通道信号

读地址通道用于传输读操作的地址和控制信息:

  • ARVALID:读地址有效信号,表示读地址传输有效。当 Master 准备好读地址时,将其置为高。
  • ARREADY:读地址就绪信号,表示 Slave 准备好接收读地址。为高时,Slave 可以接受地址。
  • ARID(可选,AXI4 独有):标识 ID,用于区分不同的读事务。
  • ARLEN:突发长度,指定突发传输中传输的数据数量。
  • ARSIZE:突发传输的宽度,表示每次突发传输的数据大小。
  • ARBURST:突发类型,定义突发传输是固定地址、递增地址还是包装突发。
  • ARLOCK:锁信号,表示是否需要独占访问资源。
  • ARCACHE:缓存类型信号,指示访问类型(缓存、缓冲等)。
  • ARPROT:保护类型信号,用于定义访问的权限和安全属性。
  • ARQOS:服务质量信号,用于指示 QoS 等级。

6. 读数据通道信号

读数据通道用于从 Slave 传输数据到 Master:

  • RVALID:读数据有效信号,表示读数据传输有效。Slave 准备好传输数据时将其置为高。
  • RREADY:读数据就绪信号,表示 Master 准备好接收数据。
  • RID(可选,AXI4 独有):读数据 ID,用于与 ARID 匹配,确保读数据对应正确的事务。
  • RRESP:读响应,表示读操作的状态(如 OKAY、EXOKAY、SLVERR 或 DECERR)。
  • RLAST:突发传输中的最后一个数据信号。Slave 通过该信号告知 Master 突发结束。

7. 低功耗接口信号(可选)

AXI 协议中还支持低功耗信号,用于电源管理:

  • CSYSREQ:系统请求信号,表示进入低功耗模式的请求。
  • CSYSACK:系统响应信号,表示系统已进入低功耗模式。
  • CACTIVE:系统活动信号,表示系统仍处于活动状态。

这些信号共同构成了 AXI4 和 AXI4-Lite 总线系统,它们在不同的通道中协作,实现数据传输的复杂过程。AXI4 支持高吞吐量和高带宽,适用于复杂的高速设备,而 AXI4-Lite 则简化了设计,适用于对带宽需求较低的设备。

### PCIE 教程入门使用指南 #### 什么是PCIePCI Express (Peripheral Component Interconnect Express),简称PCIe,是一种用于计算机内部组件之间高速数据传输的标准接口技术。它通过串行链路提供高带宽和低延迟的数据通信能力[^1]。 #### PCIe总线基础知识 了解PCIe的基础概念对于初学者至关重要。可以从以下几个方面入手: - **物理层结构**:包括信号引脚定义、电气特性以及链路训练机制。 - **协议栈解析**:分为事务层(Transaction Layer)、数据链路层(Data Link Layer) 和物理层(Physical Layer)[^2]。 - **拓扑架构**:单根复杂(Single Root Complex)模型及其工作原理。 #### 开发环境搭建 针对特定硬件平台如RK3588系列处理器上的PCIe配置方法可以参考实际案例文档来完成初始化设置并验证功能正常运行状态。 #### 实践操作建议 为了更好地掌握这项技能,在理论学习之外还需要参一些具体的工程项目练习: 1. **AXI桥接应用** 探索如何利用FPGA实现AMBA AXIPCIe转换器设计流程,这对于构建高效能外部设备互连方案非常有用[^3]。 2. **Xilinx FPGA开发经验分享** 学习有关于赛灵思公司提供的工具链支持下的PCIe IP核实例化过程说明资料可以帮助理解更多细节部分[^4]。 以下是基于Python模拟简单版本的PCIe读写函数示例代码片段供参考: ```python class PcieDevice: def __init__(self, base_addr): self.base_address = int(base_addr) def read(self, offset=0): addr = self.base_address + offset value = None # Replace with actual hardware access code. return value def write(self, data, offset=0): addr = self.base_address + offset status = False # Replace with actual hardware access code. return status ```
评论 45
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值