现代 PC 视频硬件是否支持硬件中的 VGA 文本模式,或者 BIOS 是否模拟它(使用系统管理模式)?

Pet*_*des 13 performance assembly bios vga x86-16

当您将一个字节(例如(0x31)存储到物理线性地址的VGA 文本(模式 03)帧缓冲区中时),在以 16 位传统 BIOS MBR 模式启动的现代 PC 硬件上究竟发生了什么? 将该地区MTRR设置为 UC商店有多慢在一台 Kaby Lake iGPU 笔记本电脑上的实验测试表明,WC 上的 clflushopt 与 VGA 内存的 UC 速度大致相同。但没有 clflushopt,存储到 WC 内存永远不会离开 CPU 并且根本不更新屏幕,运行速度超快.)'1'B8000mov [es:di], eaxmov

如果它不是每个商店的 SMI,是否有任何方法可以在用户空间中的一块 WB 内存上估算此成本,以进行性能实验而无需实际重新启动到实模式?(例如,使用 BSS 页面作为实际上并不在任何地方显示的假装帧缓冲区)。

相应的字体字形在下一次刷新时出现在屏幕上,但硬件扫描是否真的从 VRAM(或 iGPU 的 DRAM)读取该 ASCII 字符并动态映射到位图字体字形?或者每个存储或每个 vblank 都有一些软件拦截,所以真正的硬件只需要处理位图帧缓冲区?


众所周知,传统 BIOS 引导使用系统管理模式 (SMM)将 USB kbd/鼠标模拟为 PS/2 设备。我想知道它是否也用于 VGA 文本模式帧缓冲区。我认为它用于VGA的I /模式的设置O端口,但它是合理的,文本的framebuffer可以通过硬件来支持。但是,大多数计算机将所有时间都用于图形模式,因此忽略对文本模式的硬件支持似乎是供应商可能想要做的事情。(OTOH这个博客表明自制 verilog VGA 控制器可以相当简单地实现文本模式。)

我对在 Intel Skylake 中使用 iGPU 的系统特别感兴趣,但会对来自 Intel 和 AMD 的早期/晚期 iGPU 以及新的或旧的独立 GPU 感兴趣。

(包括 AMD 和 NVidia 以外的供应商;有一些 Skylake 主板带有 PCI 插槽,而不是 PCIe。如果现代 GPU 固件驱动程序确实模拟文本模式,大概有一些带有硬件 VGA 文本模式的旧 PCI 视频卡。也许这样的卡可以使商店只是一个 PCI 事务,而不是一个 SMI。)

我自己的桌面是华硕 Z170 Pro Gaming 主板中的 i7-6700k,没有附加卡,只有 iGPU,在 DVI-D 输出上有一个 1920x1200 显示器。我不知道@Eldan 正在测试的 Kaby Lake i5-7300HQ 系统的详细信息,只知道 CPU 型号。


从 2011 年开始找到Phoenix BIOS 的专利 US20120159520使用 uefi 模拟旧视频。他们没有要求视频硬件供应商提供 UEFI本机 16 位实模式选项 ROM 驱动程序,而是提出了一个实模式 VGA 驱动程序(int 10h函数等),它通过 SMM 挂钩调用供应商提供的 UEFI 视频驱动程序。

摘要
[...] 通用视频选项 ROM 通知通用视频 SMM 驱动程序对视频服务的请求。可以使用软件系统管理中断(SMI)来执行这种通知。收到通知后,通用视频 SMM 驱动程序会将视频服务请求通知给第三方 UEFI 视频驱动程序。第三方视频驱动程序向操作系统提供请求的视频服务。通过这种方式,第三方 UEFI 图形驱动程序可以支持多种操作系统,甚至是那些本身不支持 UEFI 显示协议的操作系统。

大部分描述都涵盖了处理int 10h调用和类似已经明显通过 IVT 捕获的内容,因此可以轻松地运行有意触发 SMI 的自定义代码。相关部分是他们描述的直接存储到文本模式帧缓冲区的内容,即使对于不触发任何软件或硬件中断的代码也需要工作。(除了硬件在此类商店上触发 SMI,他们说如果支持,他们可以使用。)

文本缓冲区支持

[0066] 在某些实施例中,应用程序可以直接操纵VGA的文本缓冲区。在这样的实施例中,通用视频SMM驱动器130以两种方式之一支持这一点,这取决于硬件是否在对740KB-768KB存储器区域(文本缓冲器所在的位置)的读/写访问时提供SMI陷印

[0067] 当SMI捕获可用时,硬件在每次读取或写入访问时生成SMI。使用SMI陷阱的陷阱地址,可以计算准确的文本列和行,并访问虚拟文本屏幕中的相应行和列。

或者,为该区域启用正常存储器,并且使用周期性SMI,通用视频SMM驱动程序130扫描模拟硬件文本缓冲区中的变化并更新由视频驱动程序维护的相应虚拟文本屏幕。在这两种情况下,当检测到变化时,在虚拟文本屏幕上重新绘制字符。

这只是一个 BIOS 供应商的专利,并没有告诉我们大多数硬件的实际工作方式,或者其他供应商是否做不同的事情。不过,它实际上确实确认了某些硬件存在,这些硬件可以困在该范围内的商店中。(除非这只是他们决定在专利中涵盖的假设可能性。)

对于我想到的用例,仅在屏幕刷新时捕获会比在每个商店上捕获快得多,所以我很好奇哪种硬件/固件以哪种方式工作。


这个问题的动机

优化第 7 代英特尔酷睿视频 RAM 中递增的 ASCII 十进制计数器- 将 ASCII 文本计数器的新数字重复存储到相同的几个字节的视频 RAM 中。

我在 Linux 下的 32 位用户空间中,在 WB 内存上测试了该代码的一个版本,希望通过movnti不同的方式让 CPU 在每次存储后将其 WC 缓冲区同步到视频 RAM(或者偶尔在定时器中断)。但是,如果实模式引导加载程序的情况不只是存储到 DRAM,而是触发 SMI,那么这是不现实的。

在 WB 内存上,movnti使用 a刷新存储lock xor byte [esp], 0比使用 刷新要快一些clflushopt。但是@Eldan 报告说,在对 MTRR 进行编程以使其成为 WC 后,VGA 内存上的速度没有提高。(并且与原始执行普通存储的速度相同,表明默认情况下 VGA 帧缓冲区是 UC。一些较旧的 BIOS可以选择使 VGA 内存 WC,他们称之为 USWC = Uncached Speculative Write Combining。)

这不是现实世界的问题,所以我不是在寻找实际的解决方法;尽管知道手动将像素字节存储到 VGA 图形模式是否会快得多会很有趣。


概括

  1. 是否有任何/所有真实的现代系统在每个存储中触发 SMI 到文本模式帧缓冲区?
  2. 如果不是,我们可以使用 movnti + WB 内存上的用户空间中的东西将 WC store+clflush 近似到帧缓冲区吗?所以我们可以很容易地分析perf性能计数器。
  3. 如果不同的 BIOS 和/或硬件使用不同的策略,那么这些策略是什么?(我不想要细节,只是像“SMI every vblank to sync the VGA framebuffer to the actual hardware framebuffer”这样的高层次)
  4. 具有硬件 VGA 文本模式的 PCIe 或 PCI 视频卡会比集成 GPU 实际执行的速度更快吗?我猜测实际的 PCIe 写入事务会比等待存储命中 DRAM 慢,但是 PCIe 写入将比每个存储上的 SMI 便宜。大致/数量级比较会很有趣。

这些问题都是高度相关的,但如果没有像我预期的那样重叠,我可以将其分开。

Bre*_*dan 9

是否有任何/所有真实的现代系统在每个存储中触发 SMI 到文本模式帧缓冲区?

对于显卡,我非常怀疑。自 1980 年代以来,显卡制造商已将“从字符+属性中获取像素数据”逻辑内置到硬件中(它早于 VGA,自 CGA 以来没有太大变化),只需将该逻辑剪切并粘贴到每个较新的设计中,而不必太在意它.

对于根本不是视频卡的东西(例如使用 LAN 的远程系统管理工具)我不知道但怀疑不是(通常他们使用特殊的管理 CPU 而不是主 CPU/s,这样即使计算机是关闭”)。

如果不是,我们可以使用 movnti + WB 内存上的用户空间中的东西将 WC store+clflush 近似到帧缓冲区吗?

如果您不在用户空间中,则可以更改 MTTR(在所有 CPU 上 - MTRR 必须匹配并且涉及特殊序列)以使 RAM 区域“未缓存”;或在页表中使用 PAT(比弄乱 MTRR 容易得多,特别是如果您无论如何都在使用分页,但由于仍然需要缓存一致性,行为略有不同)。如果您在用户空间中,那么您将不得不依赖操作系统/内核提供的任何内容,并且(取决于它是哪个操作系统)操作系统/内核可能根本不提供任何方法来执行此操作。

然而; 即使你找到了一种方法来使(一个区域的)RAM 不被缓存,它仍然不会非常相似,因为你将直接写入连接到 CPU 内置的内存控制器的东西(CPU 可以非常快地写入) 而不是与 PCI 链路另一端的某些东西交谈(这将具有更高的延迟和更低的 CPU 侧带宽)。即使对于集成视频(在技术上最终是相同的 RAM 芯片)写入 VRAM 也会通过非常不同的路径(受制于视频卡中的重新映射/GART/分页,受“写入模式”VGA 寄存器的影响,受以下影响)位/平面掩码 VGA 寄存器等)。

具有硬件 VGA 文本模式的 PCIe 或 PCI 视频卡会比集成 GPU 实际执行的速度更快吗?

用于从 CPU 写入 VRAM;通常集成视频比离散卡快得多(至少对于从 CPU 到线性帧缓冲区的纯写入,其中不涉及 VGA 的“写入逻辑”)。

对于极其粗略的估计;我希望对 RAM 的单次写入大约为 150 个周期,对 PCI 的单次写入接近 1000 个周期。对于 SMI,我预计在 SMI 到达 CPU 之前有几百个周期的延迟,然后是 CPU 管道刷新的成本,然后是大约 500 个周期来保存 CPU 的状态(以及返回路径上的相同加载状态);然后固件的代码必须找到 SMI 的原因(另外几百个周期?),然后才能知道这是对 VRAM 的写入而不是其他内容;然后它必须检查保存的 CPU 状态并找到并解码进行写入的指令(因为它无法知道正在写入什么数据,如果它是字节/字/双字写入等)同时考虑帐户以前的 CPU 状态(CPU 处于哪种模式、代码大小、XADD, 等等)。接下来,它必须分析(模拟)VGA 寄存器的状态(写入模式、写入掩码、平面启用、任何控制哪个 64 KiB 存储体映射到遗留区域、字体高度等)。基本上; 用于写入文本模式帧缓冲区的 SMI 仿真;我预计在固件代码忽略隐藏在大量复杂性中的一个次要但重要的细节之前,它需要花费数万个周期,导致它做错事并且无法使用。

其他注意事项

我从 2011 年发现 Phoenix BIOS 的专利 US20120159520,使用 uefi 模拟旧视频。

我怀疑这是否曾经实施过,因为我怀疑它永远不会奏效。您可以使用传统界面做太多(常见和模糊)的事情(例如检测垂直刷新,设置非标准视频模式,如“模式 X”,摆弄“显示开始”以实现平滑滚动和/或页面翻转,在 VBE 中使用“CRTC 信息”来更改 UEFI 不支持且无法通过的视频时序等)。UEFI 的第三方视频驱动程序。

取而代之的是,显卡制造商在大约 10 年的时间里并没有费心提供 UEFI 驱动程序,并且 UEFI 固件使用传统接口来模拟 UEFI 服务(通常在他们使用时破坏安全启动);直到几乎所有东西都是 UEFI。

我假设它 (SMM) 用于模式设置的 VGA I/O 端口。

我认为不是。我怀疑 SMM 可能用于视频的唯一模糊相关的事情是在早期启动期间(操作系统之前)控制笔记本电脑屏幕背光的亮度(特别是对于较旧的笔记本电脑,尤其是“盖子打开/关闭事件”)接手)。

.. 忽略对文本模式的硬件支持似乎是供应商可能想要做的事情

我仍然相信(最终,在已经过长的“混合 BIOS+UEFI”过渡阶段之后)从硬件中消除 30 多年累积的遗留混乱(A20、VGA、PS/2、PIT、PIC 等)是硬件制造商(英特尔)正在/一直在推动采用 UEFI 的主要原因之一。


Ros*_*dge 6

阅读各种现代英特尔 CPU 和平台控制器中枢 (PCH) 数据表,似乎没有实现必要的硬件。似乎没有任何方法可以响应处理器对 VGA 帧缓冲区(物理地址 0xA0000 - 0xBFFFF)的访问来生成 SMI(系统管理中断)。

CPU 中的内存控制器将对 VGA 帧缓冲区的访问路由到集成图形控制器、直接连接到 CPU 的 PCI Express 端口,或将 CPU 连接到 PCH 的 DMI 接口。虽然可以单独路由部分 VGA 帧缓冲区,但这似乎只是为了支持单独的 MDA(单色显示适配器)设备。集成图形控制器没有很好的文档记录,因此可以将其配置为在 VGA 帧缓冲区访问时生成 SMI,但这似乎不太可能。无论如何,它不适用于独立显卡。

Intel PCH 似乎也不支持生成 SMI 以响应 VGA 帧缓冲区访问。这将是它最自然的地方,因为它已经支持生成 SMI,以响应对键盘控制器、IDE 控制器和其他传统设备的 I/O 访问。可能有一些未记录的功能可以执行此操作,但它并未包含在 PCH 数据表中给出的可能 SMI 源列表中。

理论上,主板制造商可以通过 PCI Express 端口将假 VGA 设备连接到 PCH,然后使用 PCH GPIO 引脚生成 SMI。但是,我不确定这会在实践中起作用。到 CPU 获得 SMI 时,它本可以继续执行其他指令,并且无法在访问帧缓冲区时检查 CPU 状态。

(SoundBlaster Live 上的 SoundBlaster 16 仿真也发生了类似的问题。当访问传统 SoundBlaster 端口时,它会生成一个 PCI SERR#,这会在 CPU 上生成一个 NMI。不幸的是,该仿真在许多 Pentium 4 主板上会中断,因为NMI 将在下一条或后续指令到达。)