OBFF (Optimized Buffer Flush and Fill)

1. 背景


随着电源管理机制越来越完善,处理器和其他系统组件的功耗越来越低,而像 PCIe 组件这样的外围设备在 PC 系统功耗中占据的比重越来越大。虽然早期的 PCIe 允许一些软件和硬件电源管理,但是并没有把电源管理策略与系统的协调放在一个高优先级,所以软件的控制也很有限。


缺乏系统与电源管理策略之间的协调会导致一个很明显的问题:某些时候,系统可能已经进入睡眠状态 (sleep state)了,而 PCIe 设备可能还处于工作状态。这些 PCIe 设备可能会产生中断或者 DMA 数据传输请求,虽然这些请求的优先级可能并不高,但也会导致系统从睡眠状态唤醒,这样就破坏了节能的目标。


还有一种情况,PCIe 设备在向系统提交请求后,并不一定需要即时响应,只要在某个时间范围内得到响应即可。如果系统不知道 PCIe 设备能够容忍的响应时间,那就会默认立即响应,这样会导致系统进入低功耗模式的时间比较短或者频繁的在低功耗与非低功耗模式之间来回切换。如果系统能知道 PCIe 设备能够容忍的响应时间,就可以合理的安排对设备请求的响应,在允许的时间范围内,可以把请求积攒起来,在某一个时刻统一进行响应。这样,系统就能有比较集中的时间处于低功耗模式。

2. OBFF(Optimized Buffer Flush Fill)


OBFF 给 PCIe 设备提供了一种获取系统电源状态的机制。利用 OBFF,PCIe 设备就可以选择与系统进行数据交互的最优时间。

2.1 问题


对于具有总线主控功能的设备(bus-master capable devices)来说,如果不知道系统当前的电源状态,那么它们可能会在某些不合适的时间提交请求。

在这里插入图片描述


Figure 16-31 展示一个比较差的电源管理系统场景:系统中有 3 个 PCIe 终端设备(Endpoint),而且每个设备提交申请的时间比较散乱。这种场景下,系统能够进入 Idle 状态的时间就很短。

在这里插入图片描述


Figure 16-32 展示一个改善后的电源管理系统场景:该场景下,相同类型的请求会被攒到一起进行统一响应。这样,系统就可以有大块的时间进入 Idle 状态。很明显,这种模式能够达到不错的电源管理效果,而且实现起来并不复杂。只要 PCIe 设备能够查询当前系统的电源状态,并且知道在当前状态下该做些什么就可以。

2.2 解决方案


通过 OBFF,系统告知 PCIe 设备在哪些时间进行数据传输。OBFF 只是提供一个建议时间,PCIe 设备可以忽略 OBFF 信息,在它想要发请求的任意时刻发送请求(这样就导致功耗比较大,所以最好还是按照 OBFF 的建议来做)。有两种方式完成 OBFF 信息的交互:(1)通过向 Endpoint 发送消息(message);(2)控制 WAKE# 引脚。在两种方式都支持的情况下,优先选择 WAKE# 引脚的方式。只有在 WAKE# 引脚不能用的时候,再去选择发送消息(message)的方式。


在这里插入图片描述


Figure 16-33 展示了 OBFF 的信息传输过程。在本例中,由于两个 Switch 之间不支持 WAKE# 引脚连接,所以同时用到了消息(message)和 WAKE# 引脚两种信息传输方式。上面的 Switch 收到来自 Root Complex WAKE# 引脚的信息后,会将其转化成消息(message)发送给下面的 Switch。

2.2.1 使用 WAKE# 引脚


以前,WAKE# 只有一个功能:PCIe 组件使用该引脚通知系统恢复该 PCIe 组件的主电源供电(低功耗情况下,系统可能会移除 PCIe 组件的主电源)。


引入 OBFF 机制后,该引脚被用来向 PCIe 组件传递当前系统的电源状态。这种方式的协议很简单,只需要按照一定规律改变 WAKE# 引脚的电平,就可以表示出三种状态:

  • CPU Active:系统处于活跃状态,可以进行任意类型的事务交互。
  • OBFF:可以进行系统内存访问,可以读写系统内存;除此之外其他类型的事务交互都需要等到更高等级的电源状态。
  • Idle:等待进入更高等级的电源状态之后,启动。

在这里插入图片描述


当处于 CPU Active 或者 OBFF 状态时,建议在 10 us 之内不要进入 Idle 状态。这样可以给 PCIe 组件足够的时间去处理之前 Idle 状态下积攒的未被处理的事务。但是,由于 10 us 只是一个建议,所以 PCIe Endpoint 也不要盲目的认为系统会在 CPU Active 或者 OBFF 状态保持足够的时间。


系统可以在真正进入 Idle 状态之前,先通过 WAKE# 提前发出切换到 Idle 状态的信号,这样收到信号的 PCIe 组件就知道该结束事务传输了。


这种提前通知的机制,可以避免 PCIe 组件在系统刚进入 Idle 状态时就发起事务传输,导致系统从 Idle 状态唤醒。


按照协议的建议,系统的这种提前通知与真正进入 Idle 状态的通知之间的间隔时间要尽量的短一些。


有趣的是,WAKE# 引脚仍然能支持它最初的功能:PCIe 组件使用该引脚通知系统恢复该 PCIe 组件的主电源供电。这种情况下,当某个 PCIe 组件尝试通知系统恢复它的主电源供电时,可能会被其他监听 WAKE# 引脚的 PCIe 组件误认为是 OBFF 信息。为了解决这个问题,协议规定:如果 PCIe 组件无法清晰的理解 WAKE# 引脚的变化所指示的信息,那么该组件就可以认为当前系统处于 CPU Active 状态。

2.2.2 使用 OBFF 消息(OBFF Message)


OBFF 消息(OBFF Message)只能从 Root Complex 发送到其他 PCIe 组件。消息格式如下图:

在这里插入图片描述


Routing Type = 0b100,表示 Point-to-Point 类型。
OBFF Code 有 3 中有效值,其它都是 reserved code:

  • 0b1111:CPU Active
  • 0b0001:OBFF
  • 0b000b:Idle
  • 其他:reserved code


如果收到的 OBFF 消息中,OBFF Code的值是 reserved code,那么 PCIe 组件可以认为当前系统处于 CPU Active 状态。


如果 PCIe 组件不支持 OBFF 或者还没有使能 OBFF,那么当它收到 OBFF 消息时,需要按照 Unsupported Request类型来处理(返回的 Completion 中,将 UR 状态位设置为 1)。


PCIe 配置空间中的 Device Capability 2 寄存器指示了 PCIe 设备是否支持 OBFF,如下图所示:

在这里插入图片描述


PCIe 配置空间中的 Device Capability 2 寄存器指示了 PCIe 设备是否使能 OBFF,如下图所示:

在这里插入图片描述

本文中的图片来自MindShare, Inc 经典书籍《PCI Express Technology》。

更多 PCIe 知识,点击该链接。

  • 8
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
"New dependencies optimized"可以理解为"新的依赖优化"。这句话可以用来描述一种新的优化依赖关系的情况。 在软件开发中,依赖关系指的是一个组件或模块对其他组件或模块的依赖。当有新的依赖关系出现时,我们通常需要对其进行优化,以确保系统的性能、可靠性和可维护性。 优化依赖关系可以通过以下几个方面实现: 1. 降低组件间的耦合度:耦合度是指组件之间相互依赖的程度。通过降低耦合度,可以减少不必要的依赖关系,从而提高系统的灵活性和可维护性。 2. 精简依赖项:对于已经确定为必要依赖的组件,我们可以对其进行精简,去除不必要的部分,以减少系统的负担,提高性能。 3. 使用轻量级的依赖库:在选择依赖库时,可以优先选择轻量级的库,以减少内存占用和加载时间。 4. 更新依赖库版本:不断更新依赖库的版本,可以获得更好的性能和新特性,同时修复已知的问题和漏洞。 5. 增加缓存机制:对于频繁使用的组件或数据,可以采用缓存机制,减少对依赖组件的直接访问,提高系统的响应速度。 通过上述的优化措施,我们可以有效地提升系统的性能和可维护性,使其更加稳定和高效运行。"New dependencies optimized"表明我们已经针对新的依赖关系进行了优化,从而使系统能够更好地满足需求并提供更好的用户体验。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值