前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【译文】【第一章②】Mindshare PCI Express Technology 3.0

【译文】【第一章②】Mindshare PCI Express Technology 3.0

作者头像
空白的贝塔
发布2021-12-27 16:33:23
9220
发布2021-12-27 16:33:23
举报
文章被收录于专栏:摸鱼范式

原文:Mindshare

译者:Michael ZZY

校对: LJGibbs

欢迎参与 《Mindshare PCI Express Technology 3.0 一书的中文翻译计划》

https://gitee.com/ljgibbs/chinese-translation-of-pci-express-technology

扫描二维码进入仓库

1.4 PCI总线体系结构透视探究(PCI Bus Architecture Perspective)

1.4.1 PCI事务模型

PCI同先前的总线模型一样,在数据传输上使用三种模型:Programmed I/O(PIO)、Peer-to-peer、以及DMA。这些模型的图解如图 1‑6所示,接下来的几个小节将对它们进行描述。

1.4.1.1 Programmed I/O(PIO)

PIO在早期PC中被广泛使用,因为设计者不愿意增加设备中由于事务管理逻辑而带来的成本开销,以及额外增加的复杂度。在当时,处理器比任何其他设备工作的都要快,所以在这个模型中,处理器包揽了所有的工作。举例来说,当一个PCI设备向CPU发出中断,并表示它需要向memory中放入数据,则由CPU最终将数据从PCI设备中读出并放入一个内部寄存器中,然后再将这个内部寄存器的值复制进memory中。反之,如果数据要从memory移动到PCI设备中,那么软件会指示CPU将memory中的数据读出至内部寄存器中,然后再将内部寄存器的值写入到PCI设备中去。

这样的操作流程虽然可行,但是效率却比较低,其主要有两个原因。第一个原因,每一次数据传输都需要CPU开销两个总线周期。第二个原因,在数据传输过程中CPU都要忙于数据传输而不能做其他更有意义的任务。在早期,这是一种最快速的传输方式,而且单任务处理器也没有其他的任务要做。然而这种低效的方式显然不适用于更为先进的系统中,因此这种方式已不再是数据传输的常用方式,取而代之首选方法的是下一节将讲述的DMA方法。然而为了使软件与设备交互,Programmed IO仍然是一种必要的事务模型。

图 1‑6 PCI事务模型

1.4.1.2 Direct Memory Access(DMA)

在传输数据的方法上,一种更为高效的方式成为DMA(Direct Memory Access,直接内存访问)。在这个模型中有另一种设备称为DMA Engine(DMA引擎),由它来代表处理器来负责与掌握从memory向外设进行数据传输的各种细节操作,这就将这个繁琐的任务从CPU卸载了下来。一旦CPU将起始地址(starting address)和数据字节总量(byte count)写入DMA Engine,DMA Engine将自己处理总线协议与地址排序。这样的做法对PCI外设来说并不引入新的变化,可以让外设们保持它们的低成本设计目标。后来,经过集成性改进,外设自身可以集成入这种DMA功能,这样它们就不再需要一个外部的DMA Engine。这些设备有能力处理自己发起的总线传输,我们将它们称为总线主设备(Bus Master device)。

图 1‑3就是一个PCI总线上的总线主设备正在进行事务的过程。北桥可以对地址进行译码,以此来识别自己是否是这个事务的Target,比如北桥译码后发现地址与自己相匹配则认为自己是这个事务的Target。在总线周期中的数据传输阶段,数据在总线主设备与北桥之间传输,北桥即是数据传输的Target。北桥继而根据请求的事务内容,发起 DRAM 读写操作,与系统内存进行数据通信。在数据传输完成后,PCI外设可以产生一个中断来通知系统。DMA提升了数据传输效率,因为这种方式在搬移数据时不需要CPU的参与,那么对于CPU来说,只需要一个总线周期的开销,将起始地址和总数据量写入DMA Engine,即可完成高效的数据块搬移(move a block of data)。

1.4.1.3 Peer-to-Peer(点对点)

如果一个设备能够作为总线主设备,那么它就提供了一个有趣的作用。一个PCI总线Master可以发起针对其他PCI设备的数据传输,而对于PCI总线自身来说这整个事务都是在本地进行的,并未引入任何其他系统资源。因为这个事务是在总线上的两个设备之间进行的,且这两个设备被认为是总线中两个对等的节点,因此这个事务被称作一个“点对点”的事务。显然,这种事务非常高效,因为系统中其余的部分仍然可以自由的完成其他的任务。然而,在实际场景中点对点事务很少被使用,这是因为Initiator和Target通常不会使用相同的数据格式,除非二者都是由一个供应商制造的。因此,数据一般必须要首先发送到memory,在那里由CPU在数据传输到Target之前,对其进行格式转换,而这就阻碍并破坏了点对点传输的设计目标。

1.4.2 PCI总线仲裁

思考图 1‑2,因为当今的PCI设备基本都能作为总线Master,所以它们都可以进行DMA与peer-to-peer的数据传输。在像PCI这种共享总线的体系结构中,各设备需要轮流占用总线,因此当一个设备想要发起事务时必须首先向总线仲裁器请求总线所有权(ownership)。仲裁器将查看当前所有的请求,并使用一些特定的仲裁实现算法来决定哪个Master可以下一个占用总线。PCI协议规范并没有描述这个仲裁算法,但是有声明这个仲裁必须是“公平”的,不得在访问中差别对待任何一个设备。

仲裁器可以在上一个占用总线的Master还正在进行数据传输时就决定出下一个占用总线的设备,这样总线上就不需要引入额外的时延来对下一个总线所有者进行排序。因此,总线仲裁器的仲裁作用发挥在“幕后”,被称为“隐藏”的总线仲裁,这是一种对早期总线协议的改进。

1.4.3 PCI低效的地方(PCI Inefficiencies)
1.4.3.1 PCI重试协议(PCI Retry Protocol)

当一个PCI Master发起一个事务,用于访问一个Target设备,而此时Target设备并未处于Ready状态,那么Target就会给出一个事务重试的信号,这种场景的示意图如图 1‑7。

图 1‑7 PCI事务重试机制

考虑接下来给出的例子:北桥发起一个读memory事务,希望从以太网设备中读取数据。这个以太网设备Target响应这个事务,请求并参与到总线周期中来。然而,这个以太网设备Target此刻并没有立即将数据返回给北桥Master。这个以太网设备此时有两个办法来推迟这次数据传输。第一个办法就是在数据传输中插入等待态(wait-state)。如果过程中仅需插入少量的等待态,那么数据的传输还能算是比较有效率。但是如果Target设备需要延迟更多的时间(从事务被发起后延迟16个时钟周期以上),那么就需要用第二种办法了,第二种办法就是Target发出一个STOP#信号来表示事务重试(retry)。Retry操作是通知Master在数据没有传输前就提前结束总线周期。这样做可以防止总线长时间处于等待状态而降低了总线效率。当Master接收到Target发来的Retry请求,Master至少等待2个时钟周期,然后必须重新向总线发起仲裁请求,当再次获得总线的使用权之后重新发起相同的总线周期。在当前总线Master正在处理Retry的这段时间中,仲裁器可以将总线使用权授予其他的Master,以便于PCI总线能被更有效率的利用起来。当此前执行Retry的Master再次占用总线并重新启动与此前相同的总线周期时,Target可能也已经准备好了需要传输的数据,并参与到总线周期中进行数据传输。否则,若Target仍然未准备好,那么它将会再次发起Retry,按照这样的流程循环下去直到Master成功完成了数据传输。

1.4.3.2 PCI断开连接协议(PCI Disconnect Protocol)

当一个PCI Master发起一个事务来访问一个Target,并且如果这个Target可以传输至少一个双字(doubleword,后面使用dw简写)的数据,但是它无法完成整个完整的全数据量的传输,那么它将会在它无法继续进行传输时断开与事务操作的连接。这种场景的示意图如图 1‑8所示。

考虑接下来给出的例子:北桥发起一个突发读memory事务(burst memory read),希望从以太网设备中读取数据。以太网Target设备响应了请求并参与到这个总线周期中来,传输了部分数据,但是随后不久把已有的所有数据都发送光了,却依然没有达到Master需要的数据总量。以太网设备Target此时有两个选择来延迟数据的传输。第一个选择是在数据传输阶段插入等待态,然后自身也同时在等待收到新增的数据。如果过程中仅需插入少量的等待态,那么数据的传输还能算是比较有效率。但是如果Target设备需要延迟更多的时间(PCI协议规范中允许在数据传输中途最多有8个时钟周期的等待态,这里区别于上一节Retry中的16个周期,那是因为那时传输还没开始,而这8个周期针对的是传输已经开始了一段时间的传输中途等待),Target必须发出断开连接的信号。要断开连接,Target需要在总线周期运行中将STOP#置为有效,这样就能告知Master提前结束总线周期。Disconnect与Retry的一个区别就在于,Disconnect有数据已经被传输,而Retry则是数据传输根本就没开始。Disconnect这种操作也让总线避免长时间处于等待态。Master至少等待2个时钟周期,然后才能再次向总线发起仲裁请求,当再次获得总线的使用权之后就可以再次访问刚才断开连接的设备地址,继续完成此前断开未完成的总线周期。在当前总线Master正在经历Disconnect的这段时间中,仲裁器可以将总线使用权授予其他的Master,以便于PCI总线能被更有效率的利用起来。当此前经历Disconnect的Master再次占用总线并准备继续此前未完成的总线周期时,Target可能也已经准备好了需要继续传输的数据,并参与到总线周期中继续完成数据传输。否则,若Target仍然未准备好,那么它将会再次发起Retry或者Disconnect,然后按照这样的流程循环下去直到Master成功完成了所有数据的传输。

图 1‑8 PCI事务断开连接机制

1.4.4 PCI中断处理(PCI Interrupt Handling)

PCI设备使用4个边带信号(sideband)作为中断信号,分别为INTA#、INTB#、INTC#、INTD#,并从中选取一个来向系统发送中断请求,即使用4个中断信号中的1个来发送中断请求。当其中一个中断引脚被置为有效时,单CPU系统的中断控制器将会对中断作出响应,相应的方式为将INTR(interrupt request)信号置为有效,将中断请求发送给CPU。后来出现的多CPU系统不再适用这种单信号线输入作为中断的方式,因此进行了改进,将中断改为了APIC(Advanced Programmable Interrupt Controller)模型,在这种模型中中断控制器将会向多CPU发送报文(message)而不是向其中一个CPU发送INTR信号。不过无论中断传输模型是什么,接收到中断的CPU都必须确认中断来源,然后为中断提供服务。传统的模型需要好几个总线周期来完成确认中断和服务中断的操作,效率不是很高。APIC模型会比传统模型好一些但是也依然存在改进的空间。

1.4.5 PCI错误处理(PCI Error Handling)

可选地,PCI设备可以在事务进行期间,检测并报告接收地址或者数据信号中的奇偶校验错误。在事务进行期间,PCI对总线上大部分信号进行奇偶校验,并通过PAR信号表示计算的偶校验位结果。如果传输的数据或者地址信息中为逻辑电平1的比特数量是奇数,那么就将PAR信号置为1,以此来使得“电平1”的比特数量为偶数个。Target设备在接收到数据或地址时将会进行校验检查错误。奇偶校验(在这里为偶校验)的方法仅在有奇数个信号出错时才能检测到。如果设备检测到数据的奇偶校验错误,它将把PERR#(parity error)置为有效。这有可能是一个可以恢复的错误,因为例如对于memory读取来说,只需要再次发起相同的事务就可以解决问题。然而,PCI自身并不包含任何的自动的或是基于硬件的错误恢复机制,因此软件将完全负责去进行错误处理。

图 1‑9 PCI错误处理

然而,上面所说的是数据出错的情况,若地址校验出错则情况不同。在图 1‑9的例子中,地址信息损坏,这导致一个Target匹配上了这个错误的地址。我们无法得知损坏的地址信息变成了什么,也无法得知总线上哪个设备匹配上了这个错误的地址,所以对于这种情况就不存在能够简单进行错误恢复的方法。因此,这种类型的错误将会导致SERR#(system error)被置为有效,之后系统通常会调用错误处理程序。在老式机器中,为了预防引起更进一步的错误,将会强行让系统停止工作,从而导致出现“蓝屏死机”。

1.4.6 PCI地址空间映射(PCI Address Map)

PCI体系结构支持3种地址空间,如图 1‑10所示,包含:Memory(内存)、I/O、Configuration Address Space(配置地址空间)。x86处理器可以直接访问Memory和I/O空间。一个PCI设备映射到处理器内存地址空间,可以支持32或64位寻址。在I/O地址空间,PCI设备可以支持32位寻址,但是因为x86 CPU仅使用16位的I/O地址空间,所以许多平台都会将I/O空间限制在64KB(对应16bit)。

图 1‑10地址空间映射

PCI还引进了第三种地址空间,称为配置空间,CPU只能对它进行间接访问而非直接访问。PCI设备中的每个Function(功能)都包含专为配置空间所准备的内部寄存器,这些寄存器对于软件来说是可见的,并且软件可以通过一个标准化的方式来控制它们的地址与资源,这为PC提供了一个真正的即插即用(plug and play)的环境。每个PCI Function最多可以有256 Bytes的配置地址空间。考虑到PCI最多可支持单个设备含有8个Function、每路总线含有32个设备、单个系统包含256路总线,那么可以得到一个系统的配置空间总量为:

256B/Function *8Function/device * 32devices/bus *256buses/system =16MB,

即一个系统的配置空间总大小为16MB。

因为x86 CPU无法直接访问配置空间,所以它必须通过IO寄存器进行索引(然而在PCI Express中引入了一种新方法来访问配置空间,这种新方法是通过将配置空间映射入内存地址空间来完成的)。在传统模型中,如图 1‑10所示,使用了一种被称为配置地址端口(Configuration Address Port)的IO端口,它位于地址CF8h-CFBh;还使用了一种被称为配置数据端口(Configuration Data Port)的IO端口,它位于地址CFCh-CFFh。关于通过这种方法以及通过内存映射方法访问配置空间的细节将会在下一节进行解释。

1.4.7 PCI配置周期的生成(PCI Configuration Cycle Generation)

由于IO地址空间的大小是有限的,传统模型的设计上对地址十分保守。在IO空间中常见的做法是令一个寄存器来指向一个内部位置,然后用另一个寄存器来进行数据的读取或写入。PCI的配置过程包含如下两步。

l 第一步:CPU产生一个IO写,写入的位置为北桥中IO地址为CF8h的地址端口(Address Port),这样就给出了需要被配置的寄存器的地址,即“用一个寄存器来指向一个内部位置”。如图 1‑11所示,这个地址主要由三部分组成,通过这三部分就可以定位一个PCI Function在拓扑结构中的位置,它们为:在256条总线中我们想访问哪一条总线、在该总线上的32个设备中访问哪一个、在该设备的8个Function中访问哪一个。除了这些以外,唯一还需要提供的信息是要确认访问这个Function的64dw(256Bytes)中的哪个dw。

l 第二步:CPU产生一个IO读或者IO写,操作的位置为北桥中的地址为CFCh的数据端口(Data Port),即“用另一个寄存器来进行数据的读取或写入”。在此基础上,北桥向PCI总线发起一个配置读事务(configuration read)或配置写事务(configuration write),事务要操作的地址即为步骤一中地址端口中所指定的地址。

图 1‑11配置地址寄存器

1.4.8 PCI Function配置寄存器空间(PCI Function Cfg Reg Space)

每个PCI Function可以包含最多256Bytes的配置空间。这个配置空间起始的64Bytes包含一个被称为Header(配置空间头)的结构,剩余的192Bytes用来支持一些其他可选功能。系统配置首先由Boot ROM固件来执行,在操作系统被加载完成后,它将重新对系统进行配置,重新进行资源分配。这也就是说系统配置的过程可能会被执行两次。

根据Header的类型,PCI Function被分为两个基本的类别。第一种Header称为Type 1 Header(类型1),它的结构如图 1‑12,它用于标识这个Function是一个Bridge,Bridge将会在拓扑结构上创建另一条总线。而Type 0 Header(类型0)就是用来指示这个Function不是一个Bridge(如图 1‑13)。关于Header类型的信息包含在dword3的字节2的同名字段中(Class Code字段),当软件在系统中发现某个Function时,第一件事就是要检查其Header的这个字段(软件发现系统中Function的过程称为枚举enumeration)。

关于配置寄存器空间以及枚举过程的更为详细的讲解将会稍后再进行。在这里我们只是希望你先熟悉一下各个部分是如何相互配合工作的。

图 1‑12 PCI配置Header Type 1(Bridge)

图 1‑13 PCI配置Header Type 0(非Bridge)


原文:Mindshare

译者:Michael ZZY

校对: LJGibbs

欢迎参与 《Mindshare PCI Express Technology 3.0 一书的中文翻译计划》

https://gitee.com/ljgibbs/chinese-translation-of-pci-express-technology

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-12-25,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 摸鱼范式 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.4 PCI总线体系结构透视探究(PCI Bus Architecture Perspective)
    • 1.4.1 PCI事务模型
      • 1.4.1.1 Programmed I/O(PIO)
      • 1.4.1.2 Direct Memory Access(DMA)
      • 1.4.1.3 Peer-to-Peer(点对点)
    • 1.4.2 PCI总线仲裁
      • 1.4.3 PCI低效的地方(PCI Inefficiencies)
        • 1.4.3.1 PCI重试协议(PCI Retry Protocol)
        • 1.4.3.2 PCI断开连接协议(PCI Disconnect Protocol)
      • 1.4.4 PCI中断处理(PCI Interrupt Handling)
        • 1.4.5 PCI错误处理(PCI Error Handling)
          • 1.4.6 PCI地址空间映射(PCI Address Map)
            • 1.4.7 PCI配置周期的生成(PCI Configuration Cycle Generation)
              • 1.4.8 PCI Function配置寄存器空间(PCI Function Cfg Reg Space)
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档