深入到 TLP:PCI Express 设备如何通信(第二部分)

数据链路层数据包

除了用其标头(2 个字节)包装 TLP 并在末尾添加一个 CRC(LCRC 实际上是 4 个字节)之外,数据链路层还运行自己的数据包以保持可靠的传输。这些特殊数据包是数据链路层数据包 (DLLP)。我们很快就会列出它们:

  • Ack DLLP 用于确认已成功接收的 TLP。
  • Nack DLLP 用于指示 TLP 到达时已损坏,并且需要重新传输。请注意,还有一个超时机制,以防没有看起来像 TLP 的东西到达。
  • 流控制 DLLP:InitFC1、InitFC2 和 UpdateFC,用于宣布积分,如下所述。
  • 电源管理 DLLP。

流控制

如前所述,数据链路层具有流量控制 (FC) 机制,该机制确保仅当链路伙伴有足够的缓冲区空间来接受 TLP 时才传输它。

我故意使用了“链接合作伙伴”一词,而不是“目的地”。例如,当外围设备通过交换机连接到根复合体时,它会针对交换机而不是最终目的地运行其流量控制机制。换言之,一旦TLP从外设传输,它仍然受制于交换机和根复合体之间的流量控制机制。如果途中有更多的开关,则每条腿都有自己的流量控制。

机制不是最简单的,规范中的描述会让你起鸡皮疙瘩。所以我会尽量说得很清楚。

流控制机制独立运行,用于 6(<>!) 个不同的缓冲区使用者:

  1. Posted Requests TLP 的标头
  2. Posted Requests TLP 的数据
  3. Non-Posted请求 TLP 的标头
  4. Non-Posted请求 TLP 的数据
  5. 完成 TLP 的标头
  6. 完成 TLP 的数据

这是六种信用类型。

记帐是在流量控制单元中完成的,这些单元对应于 4 DW 的流量(16 字节),始终四舍五入到最接近的整数。由于报头的长度始终为 3 或 4 DW,因此传输的每个 TLP 都会从相应的报头信用中消耗一个单位。传输数据时,消耗的单位数为TLP中的数据DW数除以16,向上四舍五入。因此,我们可以想象每个接收器处的数据桶有 <> 个字节,我们不允许在其上混合来自不同 TLP 的数据。每个铲斗都是一个流量控制单元。

现在让我们想象一下,发射器上有一个门卫,它分别计算自链路建立以来消耗的流量控制单元总数,分别用于每个信用类型。这是要跟踪的六个数字。该门卫还具有有关允许达到的每种信用类型的最大数量的信息。如果用于传输的某个 TLP 会使这些计数单位中的任何一个超过其限制,则不允许通过。可以传输另一个 TLP(受重新排序规则的约束),或者门卫只是等待限制上升。

这就是流量控制的工作方式。建立链接后,双方交换其初始限制。当每个接收方处理传入的数据包时,它会更新其链路伙伴的限制,以便它可以使用释放的缓冲区空间。UpdateFC FLLP 数据包会定期发送,以宣布新的信用额度。

好吧,我忽略了一个小细节:由于我们正在计算自链接开始以来的单元总数,因此总是存在溢出的可能性。PCIe标准为每个信用类型计数器及其限制分配一定数量的位(8位用于标头信用,12位用于数据信用),知道它们很快就会溢出。通过简单的模算术比较每个计数器及其限制,可以解决此溢出问题。因此,考虑到一些限制,不能将限制设置得太高,流量控制机制实现了上述门卫。

允许总线实体为六种配额类型中的任何一种或所有配额宣布无限配额,这意味着该特定配额类型的流量控制被禁用。事实上,端点(与交换机和根复合体相反)必须为完成标头和数据通告无限信用。换言之,端点不能拒绝接受基于流控制的完成 TLP。因此,未过帐交易的请求者必须负责通过验证其在发出请求时是否有足够的缓冲区空间来接受完成。这也适用于不允许点对点交易的根复合体。

虚拟通道

在本指南的第一部分中,我将示例 TLP 中的 TC 字段标记为绿色,并表示这些字段几乎总是为零。TC 代表流量类,是用于创建虚拟通道的标识符。这些虚拟通道只是一组单独的数据缓冲区,具有单独的流量控制积分和计数器。因此,通过选择零以外的 TC(并相应地设置总线实体),可以使 TLP 受制于独立的流量控制系统,从而防止属于一个通道的 TLP 阻塞属于另一个通道的 TLP 的流量。

从 TC 到虚拟通道的映射由每个总线实体的软件完成。无论如何,到目前为止,我所看到的现实生活中的PCIe元件仅支持一个虚拟通道VC0,因此仅使用TC0,这是规范要求的最低要求。因此,除非某些特殊应用需要这样做,否则TC在所有TLP中都将保持为零,整个问题可以忽略不计。

数据包重新排序

在分组网络中,我想到的问题之一是 TLP 在多大程度上可能以与发送方式不同的顺序到达。例如,Internet 协议(IP,如 TCP/IP)允许在途中进行任何数据包重新洗牌。PCIe 规范允许一定程度的 TLP 重新排序,事实上,在某些情况下,为了避免死锁,重新排序是强制性的。

幸运的是,这个问题也考虑了遗留的PCI兼容性问题,除非在TLP中设置了“宽松排序”位,而这种情况很少发生。这是 Attr 字段中的位之一,在本指南第一部分的 TLP 示例中标记为绿色。因此,总而言之,人们可以相信,事情会像我们与之交谈的一辆好旧巴士一样顺利进行。我们这些写入几个寄存器,然后通过写入另一个寄存器来触发事件的人可以继续这样做。为了安全起见,我关闭了 BAR 的 Prefetch 位,尽管没有任何迹象表明它与写入有任何关系。

该规范详细定义了重新排序规则,但要获得底线并不容易。因此,我将提及这些规则的一些结果。这里所说的一切都假设在所有交易中都清除了宽松的排序位。我也完全忽略了 I/O 空间(为什么要使用它?

  • 已发布的写入和 MSI 按发送顺序到达。现在,所有内存写入都已发布,而 MSI 实际上是(已发布)内存写入。因此,我们确信内存写入是按顺序执行的,如果我们在填充缓冲区(写入...)后发出 MSI,它将在缓冲区实际写入后到达。
  • 读取请求永远不会在写入请求之前到达,也不会在写入请求之前发送 MSI 之前到达。事实上,执行读取请求是等待写入完成的一种安全方法。
  • 写入请求很可能先于在它们之前发送的读取请求。此机制可防止在某些特殊情况下出现死锁。不要在等待读取完成时写入某个内存区域。
  • 特定请求的读取完成(即具有相同的标签和请求者 ID)按发送顺序到达(因此它们按地址上升的顺序到达)。不同请求的读取完成可能会被重新排序(但谁在乎)。

除此之外,任何事情都可以更改顺序或到达,包括可以在它们之间重新排序并完成读取的读取请求。

为了消除对中断消息在之前的写入操作之前到达的任何偏执,规范中的第 2.2.7 节详细说明了这一点:

用于 MSI/MSI-X 事务的请求格式与上面定义的内存写入请求格式相同,并且 MSI/MSI-X 请求在排序、流量控制和数据完整性方面与内存写入没有区别。

零长度读取请求

如前所述,在写入总线实体后从总线实体读取数据是等待写入操作真正完成的安全方法。但是,如果我们对数据不感兴趣,为什么要阅读任何东西呢?因此,他们编造了一个零长度的请求,该请求什么也没读。所有四个字节使能都被分配了零,这意味着不会读取任何内容。至于完成,规范中的第 2.2.5 节说:

如果读取请求 1 DW 指定不启用读取字节(1st DW BE[3:0] 字段 = 0000b),则相应的完成必须指定 1 DW 的长度,并包含 1 DW 的数据有效负载

因此,我们在完成时有一个DW的垃圾数据。这很公平。

有效负载大小和边界

每个携带数据的 TLP 都必须将有效负载数据 DW 的数量限制为 Max_Payload_Size,这是在配置期间分配的数字(通常为 128 字节)。此数字仅适用于有效负载,不适用于 Length 字段本身:内存读取请求的长度不受Max_Payload_Size限制(根据规范 2.2.2),但Max_Read_Request_Size限制(根据规范 2.2.7)。

因此,内存读取请求请求的数据可能超过一个 TLP 中允许的数据,因此多个 TLP 完成是不可避免的。

无论Max_Payload_Size限制如何,(内存)读取请求的完成都可以拆分为多个完成 TLP。根据规范 128.64.2,切割必须位于由 RCB 字节对齐的地址中(请求完成边界,3 字节,对于根复合体可能为 11)。如果请求未跨越此类对齐边界,则只允许使用单个完成 TLP。单个读取请求的多个内存读取完成必须按地址递增顺序返回数据(该顺序将由交换网络保留)。

最后一句话,引用规范 2.2.7:请求不得指定地址/长度组合,这会导致内存空间访问跨越 4 KB 边界。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/648421.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

抖音VR直播:沉浸式体验一键打通360度精彩

随着5G技术的发展&#xff0c;VR直播近年来也逐步进入到大众的视野中&#xff0c;相比于传统直播&#xff0c;VR直播能够提供更加丰富的内容和多样化的互动方式&#xff0c;让观众更有沉浸感和参与感。现如今&#xff0c;抖音平台也上线了VR直播&#xff0c;凭借沉浸式体验和有…

《安富莱嵌入式周报》第331期:单片机实现全功能软件无线电,开源电源EEZ升级主控,ARM 汇编用户指南,UDS统一诊断服务解析,半导体可靠性设计手册

周报汇总地址&#xff1a;嵌入式周报 - uCOS & uCGUI & emWin & embOS & TouchGFX & ThreadX - 硬汉嵌入式论坛 - Powered by Discuz! 目录&#xff1a; 1、单片机实现低配版全功能软件无线电&#xff0c;范围0.5-30 MHz&#xff0c;支持SSB、AM、FM和CW …

浏览器require加载devextreme-react组件

十几年前使用了devexpress公司的delphi元件&#xff0c;功能很强。它们的html元件devextreme&#xff0c;功能表现类似&#xff0c;也行强。 devextreme和devextreme-react&#xff0c;我使用的是23.2.3版本。 官方推荐的用法&#xff0c;都是要经过build&#xff1a; npx d…

对二值化后的管接头表面缺陷图像进行垂直和水平投影这里面的水平投影和垂直投影是什么意思?

问题描述&#xff1a; 对二值化后的管接头表面缺陷图像进行垂直和水平投影 这里面的水平投影和垂直投影是什么意思&#xff1f; 问题解答&#xff1a; 在图像处理中&#xff0c;垂直投影和水平投影是两种常用的直方图投影方法&#xff0c;用于分析图像的特征&#xff0c;特别…

GitHub Copilot 与 OpenAI ChatGPT 的区别及应用领域比较

GitHub Copilot 和 OpenAI ChatGPT 都是近年来颇受关注的人工智能项目&#xff0c;它们在不同领域中的应用继续引发热议。本文旨在分析和比较这两个项目的区别&#xff0c;从技术原理、应用场景、能力和限制、输出结果、能力与限制和发展前景等方面进行综合评估&#xff0c;帮助…

Mysql 学习(十 四)事务简介

为什么要有事务&#xff1f; 数据库的出现其实是有应用场景的&#xff0c;最好的例子就是交易&#xff0c;以前的交易是通过账本记录的&#xff0c;也就是通过纸和笔来记录&#xff0c;而数据库的出现大大提升了效率&#xff0c;但是现实中的有些问题&#xff0c;数据库也需要…

数据分析 - python 数据处理

数据处理 去除重复数据 # 删除重复值 保留重复行 第一行的数据 data.drop_duplicates(inplaceTrue, keepfirst)数据格式转化 日期格式化 data[order_date] pd.to_datetime(data[order_dt], format%Y%m%d)data[销售时间] pd.to_datetime(data[销售时间]) # 交货时间 销售…

MIT_线性代数笔记:线性代数常用计算公式

目录 1.矩阵的加法和数乘2.矩阵的乘法3.转置 Transposes 相关运算 1.矩阵的加法和数乘 2.矩阵的乘法 1)标准方法&#xff08;行乘以列&#xff09; 矩阵乘法的标准计算方法是通过矩阵 A 第 i 行的行向量和矩阵 B 第 j 列的列向量点积得到 cij。即我们常说的点积&#xff0c;也…

SIP INVITE method

在RFC 3261定义了SIP:INVITE,以下是具体内容。 当UA客户端希望发起session,例如voice call 或video call时,UAC就可以发送INVITE request。INVITE request会要求服务器建立session,然后该请求由代理转发,最终到达一个或多个可能接受邀请的UAS。 UAS 可以通过发送 2xx res…

c++ class总结

c class的使用总结 1.继承2.静态成员变量与静态成员函数3.多态4.虚函数5.纯虚函数6.友元类、友元函数6.1 友元类6.2 友元函数 1.继承 类Man、WoMan 继承于类Person。 类Man、WoMan 的实例对象都可以使用类Person中public属性的成员及成员函数。 #include<iostream>cla…

使用GtkSharp下载zip包过慢问题解决方案

背景 安装GtkSharp这个包准备使用C#进行跨平台窗体应用程序开发&#xff0c;运行时发现其需要从github上下载【https://github.com/GtkSharp/Dependencies/raw/master/gtk-3.24.24.zip】这个依赖包&#xff0c;不知道是被墙了还是咋的&#xff0c;下载超时导致运行失败。 解决…

【算法练习】leetcode算法题合集之动态规划篇

普通动规系列 LeetCode343. 整数拆分 LeetCode343. 整数拆分 将10的结果存在索引为10的位置上&#xff0c;需要保证数组长度是n1&#xff0c;索引的最大值是n&#xff0c;索引是从0开始的。 n的拆分&#xff0c;可以拆分为i和n-i&#xff0c;当然i可以继续拆分。而且拆分为n-…

django mysql in 有序返回

from django.db.models import * ordering f"FIELD(id, {,.join([str(_) for _ in ids])})" # 默认就按照算法返回的 id 排序p_data_result PeptidesDataResult.objects.using("polypeptide").filter(id__inids).values().extra(select{ordering: orderi…

Cybellum—信息安全测试工具

产品概述 由于软件和数据在汽车上的使用越来越多&#xff0c;汽车越来越“智能化”&#xff0c;汽车行业面临着重大的信息安全挑战。2021年8月&#xff0c;ISO/SAE 21434正式发布&#xff0c;标准中对汽车的信息安全提出了规范化的要求&#xff0c;汽车信息安全不容忽视。 Cyb…

Redis数据结构与底层实现揭秘

在高并发的系统开发中&#xff0c;缓存和高效的数据存储机制对于提升应用性能至关重要。Redis&#xff0c;作为其中的佼佼者&#xff0c;以其卓越的性能和丰富的数据结构赢得了开发者的青睐。本文将深入探讨Redis的数据结构及其底层实现&#xff0c;带领读者走进这个高性能数据…

CentOS7 安装PostgreSQL以及配置服务

文章目录 前言1. 安装步骤2. 连接PostgreSQL3. 配置服务配置文件所在路径设置监听地址修改数据库密码已经修改了密码,为什么没有生效?不需要密码就可以连接?设置访问权限4. 新的配置生效前言 PostgreSQL是一种功能强大的开源关系型数据库管理系统,被广泛用于各种应用程序和…

多个SSH-Key下,配置Github SSH-Key

首先&#xff0c;检查 github 的连接性&#xff0c;因为DNS污染的原因&#xff0c;很多机器ping不通github&#xff0c;就像博主的机器&#xff1a; 怎么解决DNS污染的问题&#xff0c;博主查了很多教程&#xff0c;测试出一个有效的方法&#xff0c;那就是修改hosts文件。host…

设计模式_组合模式_Composite

案例引入 学校院系展示 编写程序展示一个学校院系结构: 需求是这样&#xff0c;要在一个页面中展示出学校的院系组成&#xff0c;一个学校有多个学院&#xff0c;一个学院有多个系 【传统方式】 将学院看做是学校的子类&#xff0c;系是学院的子类&#xff0c;小的组织继承大…

代码随想录算法训练营第二天—数组02 | *977.有序数组的平方 ,209.长度最小的子数组 ,*59.螺旋矩阵II

*977.有序数组的平方 题目链接&#xff1a;https://leetcode.cn/problems/squares-of-a-sorted-array/ 文章讲解&#xff1a;https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html 视频讲解&#xff1a; https://www.bilib…

HarmonyOS 鸿蒙应用开发( 六、实现自定义弹窗CustomDialog)

自定义弹窗&#xff08;CustomDialog&#xff09;可用于广告、中奖、警告、软件更新等与用户交互响应操作。开发者可以通过CustomDialogController类显示自定义弹窗。具体用法请参考自定义弹窗。 在应用的使用和开发中&#xff0c;弹窗是一个很常见的场景&#xff0c;自定义弹窗…