【Intel-64 and IA-32 Architectures Software Developer‘s Manual】Chapter 11

本章节关于 memory cachecache control mechanismsTLBsstore buffer

文章目录

  • 11.1 Caches,TLBs and Buffers
  • 11.2 Caching Terminology(术语)
  • 11.3 Methods of Caching Avaiable
    • 11.3.1 Buffering of Write Combining Memory Locations
    • 11.3.2 Choosing a Memory Type
    • 11.3.3 Code Fetches in Uncacheable Memory
  • 11.4 Cache Control Protocol
  • 11.5 Cache Control
    • 11.5.1 Cache Control Registers and Bits
    • 11.5.2 Precedence of Cache Controls
      • 11.5.2.1 Selecting Memory Types for Pentium Pro and Pentium Ⅱ Processors
      • 11.5.2.2 Selecting Memory Types for Pentium Ⅲ and More Recent Processor Families
      • 11.5.2.3 Writing Values Across Pages with Different Memory Types
    • 11.5.3 Preventing Caching
    • 11.5.4 Disabling and Enabling the L3 Cache
    • 11.5.5 Cache Management Instructions
    • 11.5.6 L1 Data Cache Context Mode
      • 11.5.6.1 Adaptive Mode
      • 11.5.6.2 Shared Mode
  • 11.6 SELF-MODIFYING CODE
  • 11.7 IMPLICIT CACHING(PENTIUM 4, INTEL XEON, AND P6 FAMILY PROCESSORS)
  • 11.8 EXPLICIT CACHING
  • 11.9 INVALIDATING THE TRANSLATION LOOKASIDE BUFFERS(TLBS)
  • 11.10 STORE BUFFER
  • 11.11 MEMORY TYPE RANGE REGISTERS(MTRRS)
    • 11.11.1 MTRR Feature Identification
    • 11.11.2 Setting Memory Ranges with MTRRS
      • 11.11.2.1 IA32_MTRR_DEF_TYPE MSR
      • 11.11.2.2 Fixed Range MTRRS
      • 11.11.2.3 Variable Range MTRRS
      • 11.11.2.4 System-Management Range Register Interface
    • 11.11.3 Example Base and Mask Calculations
      • 11.11.3.1 Base and Mask Calculations for Greater-Than 36-bit Physical Address Support
    • 11.11.4 Range Size and Alignment Requirement
      • 11.11.4.1 MTRR Precedences
    • 11.11.5 MTRR Initialization
    • 11.11.6 Remapping Memory Types
    • 11.11.7 MTRR Maintenance Programming Interface
      • 11.11.7.1 MemTypeGet() Function
      • 11.11.7.2 MemTypeSet() Function
    • 11.11.8 MTRR Considerations in MP Systems
    • 11.11.9 Large Page Size Considerations
  • 11.12 PAGE ATTRIBUTE TABLE(PAT)
    • 11.12.1 Detecting Support for the PAT-Feature
    • 11.12.2 IA32_PAT MSR
    • 11.12.3 Selecting a Memory Type from the PAT
    • 11.12.4 Programming the PAT
    • 11.12.5 PAT Compatibility with Earlier IA-32 Processors

11.1 Caches,TLBs and Buffers

  1. Intel 64 和 IA-32 架构支持 cache、translation look aside buffers(TLBs)、buffers,这三种存储结构用于指令和数据的临时片内(片外)存储。
  2. Figure 11-1,显示了 Pentium4 和 Intel Xeon 处理器的 caches、TLBs 和 buffer。
  3. Table 11-1,显示了 Pentium4 和 Intel Xeon,P6 家族和奔腾处理器的 cache 和 buffer 的特性。
  4. CPUID 指令返回处理器的 caches 和 buffers 的大小和特征。
  5. Figure 11-2,Core i7.


Intel 64 和 IA-32 处理器可以实现四种类型的 cache line :trace cache、cache(L1)、cache(L2)、cache(L3)

  • 基于因特尔微体系结构的 Nehalem 和 Westmere 的 Croe i3、i5、i7 家族和因特尔 Xeon(至强)处理器家族。L1 cache 分为两部分:一部分用于 cache line 指令(预解码指令),另一部分用于 cache line 数据。L2 cache cache line 数据和指令。每个处理器 core 均有自己的 L1、L2。L3 cache cache line 数据和指令,由所有处理器的 core 共享。没有实现 trace cache。
  • 基于英特尔 Core 微体系结构的 Core2 处理器家族和 Xeon 处理器家族。L1 cache 分为两部分:一部分用于 cache line 指令(预解码指令),另一部分 cache line 数据。L2 cache cache line 数据和指令,在双核处理器中,L2 cache 在两个处理器内核之间共享。四核处理器有两个 L2,每个由两个处理器 core 共享。没有实现 trace cache。
  • Intel Atom(凌动)处理器。L1 cache 分为两部分:一部分用于 cache line 指令,另一部分用于 cache line 数据。L2 cache cache line 数据和指令。没有实现 trace cache。
  • Intel® Core™ Solo and Intel® Core™ Duo processors(因特尔酷睿单核和因特尔双核处理器)。同基于英特尔 Core 微体系结构的 Core2 处理器家族和 Xeon 处理器家族
  • 基于因特尔网络突发微体系结构的奔腾 4 和志强处理器(Pentium® 4 and Intel® Xeon® processors Based on Intel NetBurst® microarchitecture)。trace cache cache line 来自指令解码器的解码指令(uops)。L1 cache cache line 数据。L2 和 L3 cache line 数据和指令。双核处理器有两个 L2,每个处理器 core 一个。L3 cache 仅在某些 Xeon 上存在。
  • P6 系列处理器。L1 cache 分为两部分:一部分 cache line 指令(预解码指令),另一部分用于 cache line 数据。L2 cache line 数据和指令。P6 系列不实现 trace cache。
  • 奔腾处理器。L1 cache line 结构与 P6 系列处理器相同。没有 trace cache。L2 cache line 数据和指令,早期位于处理器芯片外部(通过系统总线访问),后期在处理器芯片上实现。

对于英特尔酷睿 i7 处理器和基于英特尔酷睿、英特尔凌动和英特尔网络爆发微体系结构、英特尔酷睿双核、英特尔酷睿单核和奔腾M处理器的处理器,L1 和 L2 高速 cache line (以及 L3 高速 cache line ,如果支持)的高速 cache line 线为 64 字节宽。处理器总是从 64 字节边界开始从系统内存中读取高速 cache line 。( 64 字节对齐的高速 cache line 从清除了 6 个最低有效位的地址开始。)

cache line 可以用 8 次传输突发事务从存储器填充。 cache line 不支持部分填充的 cache line,所以 cache line 一个双字也需要 cache line 一整行。

P6 系列和奔腾处理器中的 L1 和 L2 高速 cache line 线为 32 字节宽,从系统内存中读取的高速 cache line 线从 32 字节的边界开始(清除内存地址的 5 个最低有效位。)可以通过 4 次传输突发事务从存储器填充高速 cache line 。不支持部分填充的 cache line 。

基于英特尔 NetBurst 微体系结构的处理器中的跟踪 cache line 在所有执行模式下均可用:保护模式、系统管理模式(SMM)和真实地址模式。L1、L2 和 L3 cache line 也可用于所有执行模式。

TLB 存储最近使用的页目录和页表条目。当启用分页时,它们通过减少读取存储在系统内存中的页表所需的内存访问次数来加速内存访问。TLB 分为四组:4k 字节页的指令 TLB,4k字节页的数据 TLB;大页面(2MB、4MB 或 1GB 页面)的指令 TLB和大页面的数据 TLB。TLB 通常仅在启用分页的保护模式下有效。当分页被禁用或处理器处于实地址模式时,TLB 保持其内容,直到被显式或隐式刷新。

基于英特尔酷睿微体系结构的处理器实现一级指令 TLB 和两级数据 TLB。英特尔酷睿 i7 处理器提供二级统一 TLB。

存储缓冲器与处理器指令执行单元相关联。它允许保存对系统内存和/或内部高速 cache line 的写入,并且在某些情况下可以组合起来优化处理器的总线访问。在所有执行模式下,存储缓冲区始终处于启用状态。

处理器的 cache line 大部分对软件是透明的。启用后,指令和数据无需显式软件控制即可通过这些 cache line 。但是,了解这些 cache line 的行为可能有助于优化软件性能。

在多处理器系统中,在极少数情况下,维护 cache line 一致性可能需要系统软件的干预。对于这些罕见的情况,处理器提供特权 cache line 控制指令,用于刷新 cache line 和强制内存排序。

软件可以使用若干指令来提高 L1、L2 和 L3 cache line 的性能,包括预取、CLFLUSH 和 CLFLUSHOPT 指令以及非临时移动指令(MOVNTI、MOVNTQ、MOVNTDQ、MOVNTPS和MOVNTPD)。

11.2 Caching Terminology(术语)

IA-32 处理器(从奔腾处理器开始)和英特尔 64 处理器使用 MESI(修改、独占、共享、无效)高速 cache line 协议来保持与内部高速 cache line 和其他处理器中的高速 cache line 的一致性。

当处理器识别出从存储期读取的操作数是可高速 cache line 的时,处理器将整个高速 cache line 读取到适当的高速 cache line (L1、L2、L3、全部)中,此操作称为 cache line fill

如果下一次处理器试图访问操作数时,包含该操作数的内存位置仍被 cache line ,则处理器可以从 cache line 中读取操作数,而不是从内存中读取,此操作称为 cache hit

当处理器示图将操作数写入存储期的可高速 cache line 区域时,它首先检查该存储期位置的高速 cache line 是否存在于高速 cache line 中。如果存在有效的高速 cache line ,处理器(取决于当前有效的写策略)可以将操作数写入高速 cache line ,而不是将其写入内存,此操作成为 write hit。如果未命中(对于正被写入的存储器区域,有效的高速 cache line 不存在),处理器执行高速 cache line 填充、写分配。然后,它将操作数写入 cache line ,并且还可以将其(根据当前有效的写入策略)写入内存。如果要将操作数写入内存,则先将其写入存储缓冲区,然后在系统总线可用时从存储缓冲区写入内存。(请注意,对于奔腾处理器,写未命中不会导致 cache line 线填充;它们总是导致写入内存。对于该处理器,只有读未命中才会导致高速 cache line 线填充。)

在 MP 系统中运行时,IA-32 处理器(从因特尔 486 处理器开始)和因特尔 64 处理器能够 snoop(窥探)其它处理器对系统内存和内部 cache line 的访问。他们使用这种窥探能力来保持他们的内部高速 cache line 与系统内存和总线上其他处理器的高速 cache line 一致。例如,在奔腾和 P6 系列处理器中,如果通过窥探一个处理器检测到另一个处理器打算写入其当前以共享状态 cache line 的存储单元,窥探处理器将使其 cache line 无效,迫使其在下次访问同一存储单元时执行 cache line 线填充。

从 P6 系列处理器开始,如果一个处理器检测到(通过窥探)另一个处理器正在尝试访问其高速缓存中已修改的存储单元,但尚未写回系统内存,窥探处理器(snooping processor)将向另一个处理器发出信号(通过HITM#信号),表明高速 cache line 保持在修改状态,并将对修改后的数据进行隐式写回。隐式回写被直接传送到初始请求处理器,并被存储器控制器监听,以确保系统存储器已被更新。这里,具有有效数据的处理器可以将数据传递给其他处理器,而不实际将其写入系统存储器;但是,内存控制器有责任监听此操作并更新内存。

11.3 Methods of Caching Avaiable

处理器运行系统内存的任何区域缓存在 L1、L2 和 L3 缓存中。在系统内存的单个页面或区域中,它允许指定缓存类型(也称为内存类型,chapter 11.5),内存类型有:

  • Strong Uncacheable(UC)—— 系统内存位置不会被缓存。所有读取和写入都出现在系统总线上,并按程序顺序执行,无需重新排序。不进行推测性内存访问、页表遍历或推测性分支目标的预取。这种类型的缓存控制对于内存映射输入/输出设备很有用。当与普通内存一起使用时,它会大大降低处理器性能。FP 和 SSE/SSE2 操作对 UC 内存中操作数的行为依赖于实现。在一些实现中,对统一通信存储器的访问可能不止一次。为了确保可预测的行为,使用通用寄存器的加载和存储来访问可能具有读或写副作用的统一通信存储器。

  • Uncacheable(UC)—— 具有与强不可缓存 (UC) 内存类型相同的特征,只是这种内存类型可以通过为 WC 内存类型编程 MTRRs 来覆盖。这种内存类型在从奔腾三处理器开始的处理器系列中可用,并且只能通过 PAT 选择。

  • Write Combining(WC)—— 系统内存位置不被缓存(与不可缓存内存一样),处理器的总线一致性协议也不强制执行一致性。允许投机性读取。写入可能会被延迟,并在写入组合缓冲区(WC 缓冲区)中进行组合,以减少内存访问。如果 WC 缓冲区被部分填充,则写入可能被延迟,直到下一次发生序列化事件;例如,单指令或多指令指令、CPUID执行、对未高速缓存存储器的读或写,中断事件或锁指令的执行(包括带有 XACQUIREXRELEASE前缀的指令)。此外,XEND 指令的执行(结束事务区域)在驱逐事务区域内执行的任何写入之前,驱逐在 XBEGIN 指令的相应执行(开始事务区域)之前缓冲的任何写入。

    这种类型的缓存控制适用于视频帧缓冲区,在视频帧缓冲区中,只要写操作更新了内存,写操作的顺序就不重要,这样就可以在图形显示器上看到它们。有关缓存碳化钨内存类型的更多信息,请参见第11.3.1节“写入组合内存位置的缓冲”。这种内存类型可在奔腾专业版和奔腾二版处理器中通过对 MTRRs 编程获得;或者在从奔腾三处理器开始的处理器系列中,通过编程 MTRRs 或通过PAT选择它

  • Write-through(WT)—— 对系统内存的读写被缓存。读取来自缓存命中时的缓存行;读取未命中会导致缓存填充。允许投机性读取。所有写入都被写入缓存行(如果可能)并通过系统内存。当写入内存时,无效的高速缓存行永远不会被填充,有效的高速缓存行要么被填充,要么被无效。允许写入组合。这种类型的缓存控制适用于帧缓冲区,或者当系统总线上有设备访问系统内存,但不执行内存访问窥探时。它加强了处理器和系统内存中高速缓存之间的一致性。

  • Write-back(WB)—— 对系统内存的读写被缓存。读取来自缓存命中时的缓存行;读取未命中会导致缓存填充。允许投机性读取。写未命中会导致缓存线填充(在从P6系列处理器开始的处理器系列中),并且写操作会尽可能完全在缓存中执行。允许写入组合。回写内存类型通过消除对系统内存的许多不必要的写入来减少总线流量。对缓存行的写入不会立即转发到系统内存;相反,它们累积在缓存中。当执行回写操作时,修改后的高速缓存行被写入系统存储器。当高速缓存行需要被解除分配时,例如当新的高速缓存行被分配到已经满的高速缓存中时,回写操作被触发。它们也由用于维护缓存一致性的机制触发。这种类型的高速缓存控制提供了最好的性能,但是它要求在系统总线上访问系统存储器的所有设备能够监听存储器访问,以确保系统存储器和高速缓存的一致性。

  • Write protected(WP)—— 读取尽可能来自高速缓存行,读取未命中会导致高速缓存填充。写入被传播到系统总线,并导致总线上所有处理器上相应的高速缓存线无效。允许投机性读取。从 P6 系列处理器开始,通过对 MTRRs 进行编程,这种存储器类型在处理器系列中是可用的(参见表11-6)。


11.3.1 Buffering of Write Combining Memory Locations

对 WC 内存类型的写入不是缓存字的典型含义中的缓存。它们保留在与内部 L1、L2 和 L3 缓存以及存储缓冲区分开的内部写入组合缓冲区(WC 缓冲区)中。 WC 缓冲区不被监听,因此不提供数据一致性。缓冲写入 WC 内存的目的是让软件有一小段时间来向 WC 缓冲区提供更多修改过的数据,同时尽可能保持对软件的非侵入性。写入 WC 内存的缓冲也会导致数据崩溃;也就是说,对同一内存位置的多次写入将留下最后写入该位置的数据,而其他写入将丢失。

WC 缓冲区的大小和结构没有在体系结构上定义。适用于 Intel Core 2 Duo、Intel Atom、Intel Core Duo、Pentium M、Pentium 4 和 Intel Xeon 处理器; WC 缓冲区由几个 64 字节的 WC 缓冲区组成。对于 P6 系列处理器,WC 缓冲区由几个 32 字节的 WC 缓冲区组成。

当软件开始写入 WC 内存时,处理器开始一次填充 WC 缓冲区。当一个或多个 WC 缓冲区被填满时,处理器可以选择将缓冲区驱逐到系统内存中。驱逐 WC 缓冲区的协议取决于实现,软件不应依赖于系统内存一致性。使用 WC 内存类型时,软件必须对将数据写入系统内存被延迟这一事实敏感,并且在需要系统内存一致性时必须有意清空 WC 缓区。

一旦处理器开始将数据从 WC 缓冲区驱逐到系统内存中,它将根据缓冲区中有多少包含有效数据来做出总线事务风格的决定。如果缓冲区已满(例如,所有字节都有效),则处理器将在总线上执行突发写入事务。这导致在单个突发事务中在数据总线上传输所有 32 字节(P6 系列处理器)或 64 字节(奔腾 4 和更新的处理器)。如果 WC 缓冲区的一个或多个字节无效(例如,尚未被软件写入),处理器将使用“部分写入”事务(一次一个块,其中“块”是8 个字节)。

对于发送到内存的 WC 数据缓冲区,这将导致最多 4 个部分写入事务(对于 P6 系列处理器)或 8 个部分写入事务(对于 Pentium 4 和更新的处理器)。

WC 内存类型按照定义是弱排序的。一旦 WC 缓冲区的驱逐开始,数据就受其定义的弱排序语义的约束。在 WC 缓冲区的连续分配/解除分配之间不保持顺序(例如,写入 WC 缓冲区 1 后写入 WC 缓冲区 2 可能在系统总线上显示为缓冲区 2 后跟缓冲区 1)。当 WC 缓冲区作为部分写入被驱逐到内存时,连续的部分写入之间没有保证的顺序(例如,块 2 的部分写入可能在块 1 的部分写入之前出现在总线上,反之亦然)。

WC 传播到系统总线的唯一元素是事务原子性提供的元素。例如,对于 P6 系列处理器,完全满的 WC 缓冲区将始终作为使用任何块顺序的单个 32 位突发事务进行传播。在数据将作为部分数据被驱逐的 WC 缓冲区驱逐中,包含在同一块(0 mod 8 对齐)中的所有数据将同时传播。同样,对于从基于 Intel NetBurst 微架构的处理器开始的较新处理器,完整的 WC 缓冲区将始终作为单个突发事务传播,使用事务中的任何块顺序。对于部分缓冲区传播,包含在同一块中的所有数据将同时传播。

11.3.2 Choosing a Memory Type

最简单的系统内存模型不使用具有读或写副作用的内存映射 I/O,不包括帧缓冲区,并且对所有内存使用回写内存类型。 I/O 代理可以执行直接内存访问 (DMA) 以回写内存,并且缓存协议保持缓存一致性。

系统可以为其他内存映射 I/O 使用强不可缓存内存,并且应该始终为具有读取副作用的内存映射 I/O 使用强不可缓存内存。

双端口内存可以被认为是写入的副作用,使得相对快速的写入是可取的,因为这些写入在到达内存代理之前无法在另一个端口上观察到。系统可以将强不可缓存、不可缓存、直写或写组合内存用于帧缓冲区或包含屏幕上显示的像素值的双端口内存。帧缓冲存储器通常很大(几兆字节),并且通常写入的内容多于处理器读取的内容。将强大的不可缓存内存用于帧缓冲区会产生非常大量的总线流量,因为对整个缓冲区的操作是使用部分写入而不是行写入来实现的。为帧缓冲区使用直写内存可以取代处理器的 L2 和 L3 高速缓存以及 L1 数据高速缓存中几乎所有其他有用的高速缓存行。因此,系统应尽可能为帧缓冲区使用写组合内存。

当软件不会以受益于回写缓存的方式访问数据结构时,软件可以使用页面级缓存控制来分配适当的有效内存类型。例如,软件可能会读取一个大型数据结构一次,并且不会再次访问该结构,直到该结构被另一个代理重写。如此大的数据结构应该标记为不可缓存,否则读取它会驱逐处理器将再次引用的缓存行。

一个类似的例子是一个只写数据结构,它被写入(将数据导出到另一个代理),但永远不会被软件读取。这样的结构可以标记为不可缓存,因为软件永远不会读取它写入的值(尽管作为不可缓存的内存,它将使用部分写入写入,而作为回写内存,它将使用行写入写入,这可能不会直到另一个代理读取结构并触发隐式写回)。

在奔腾 III、奔腾 4 和更新的处理器上,提供了新指令,使软件能够更好地控制数据的缓存、预取和写回特性。这些指令允许软件使用弱排序或处理器排序的内存类型来提高处理器性能,但在必要时强制对内存读取和/或写入进行强排序。它们还允许软件更好地控制数据缓存。有关这些指令的说明及其预期用途,请参阅第 11.5.5 节,“缓存管理指令”。

11.3.3 Code Fetches in Uncacheable Memory

程序可以从不可缓存 (UC) 内存中执行代码,但其含义与访问 UC 内存中的数据不同。 在执行代码提取时,处理器永远不会推测性地从可缓存代码转换为 UC 代码。 它也从不推测性地获取导致 UC 代码的分支目标。

处理器可以多次获取相同的 UC 缓存行,以便对指令进行一次解码。 它可以在高速缓存行中解码连续的 UC 指令,而无需在每条指令之间取回。 它还可以从相同或连续的 4 KB 页中获取额外的高速缓存行,以便对一条非推测性 UC 指令进行解码(即使该指令完全包含在一行中也是如此)。

由于上述原因以及缓存线大小在未来的处理器中可能会发生变化,软件应避免将具有读取副作用的内存映射 I/O 放置在用于执行 UC 代码的同一页面或后续页面中。

11.4 Cache Control Protocol

以下部分描述了当前为 Intel 64 和 IA-32 架构定义的缓存控制协议。

在 L1 数据缓存和 L2/L3 统一缓存中,MESI(修改的、排他的、共享的、无效的)缓存协议与其他处理器的缓存保持一致。 L1 数据缓存和 L2/L3 统一缓存的每个缓存行有两个 MESI 状态标志。 每条线都可以标记为处于表 11-4 中定义的状态之一。 一般来说,MESI 协议的操作对程序是透明的。

P6 系列处理器中的 L1 指令缓存仅实现 MESI 协议的“SI”部分,因为指令缓存不可写。 指令高速缓存监视数据高速缓存中的变化以在修改指令时保持高速缓存之间的一致性。 有关缓存指令含义的更多信息,请参见第 11.6 节“自修改代码”。

11.5 Cache Control

Intel 64 和 IA-32 架构提供了多种机制来控制数据和指令的缓存以及控制处理器、缓存和内存之间的读取和写入顺序。这些机制可以分为两组:

  • 缓存控制寄存器和位(Cache control registers and bits) — Intel 64 和 IA-32 体系结构定义了几个专用寄存器和控制寄存器中的各种位以及控制缓存系统内存位置的页面和目录表条目。 L1、L2 和 L3 缓存。这些机制控制虚拟内存页面和物理内存区域的缓存。
  • 缓存控制和内存排序指令(Cache control and memory ordering instructions)——Intel 64 和 IA-32 架构提供了几个控制数据缓存、内存读写排序以及数据预取的指令。这些指令允许软件控制特定数据结构的缓存,控制内存中特定位置的内存一致性,并在程序中的特定位置强制执行强内存排序。

以下部分描述了这两组缓存控制机制。

11.5.1 Cache Control Registers and Bits

图 11-3 描述了 IA-32 处理器中的缓存控制机制。除了内存地址空间问题外,这些在 Intel 64 处理器中的工作方式相同。 Intel 64 和 IA-32 体系结构提供以下缓存控制寄存器和位,用于启用或限制对内存中各种页面或区域的缓存:

  • CD 标志,控制寄存器 CR0 的第 30 位(CD flag,bit 30 of control register CR0) — 控制系统内存位置的缓存(请参见第 2.5 节“控制寄存器”)。如果清除 CD 标志,则为整个系统内存启用缓存,但可能会被其他缓存控制机制限制为单个页面或内存区域。当设置 CD 标志时,P6 和更新的处理器系列的处理器缓存(缓存层次结构)中的缓存受到限制,而奔腾处理器则禁止缓存(请参阅下面的注释)。但是,设置 CD 标志后,缓存仍将响应监听流量。应明确刷新缓存以确保内存一致性。为了获得最高的处理器性能,控制寄存器 CR0 中的 CD 和 NW 标志都应该被清除。表 11-5 显示了 CD 和 NW 标志的交互。对于从 P6 系列开始的处理器系列,设置 CD 标志的效果与 Pentium 处理器有所不同(见表 11-5)。为确保设置 CD 标志后的内存一致性,应明确刷新缓存(请参阅第 11.5.3 节,“防止缓存”)。为 P6 和更新的处理器系列设置 CD 标志会修改缓存行填充和更新行为。此外,在这些处理器上设置 CD 标志不会强制对内存访问进行严格排序,除非 MTRR 被禁用和/或所有内存都被引用为未缓存(参见第 8.2.5 节,“加强或削弱内存排序模型”)。

  • NW 标志,控制寄存器 CR0 的第 29 位 — 控制系统内存位置的写入策略(参见第 2.5 节“控制寄存器”)。 如果 NW 和 CD 标志清除,则对整个系统内存启用回写,但其他缓存控制机制可能会限制单个页面或内存区域。 表 11-5 显示了 CD 和 NW 标志的其他组合如何影响缓存。
  • 分页结构条目中的 PCD 和 PWT 标志——控制用于访问分页结构和页面的内存类型(参见第4.9 节“分页和内存类型”)。
  • 控制寄存器 CR3 中的 PCD 和PWT 标志——控制用于访问当前分页结构层次结构的第一个分页结构的存储器类型(参见第4.9 节“分页和存储器类型”)。
  • 页目录和页表条目中的 G(全局)标志(引入 P6 系列处理器中的 IA-32 体系结构)— 控制单个页面的 TLB 条目的刷新。有关此标志的更多信息,请参见第 4.10 节“缓存翻译信息”。
  • 控制寄存器 CR4 中的 PGE(页面全局启用)标志 — 启用具有 G 标志的全局页面的建立。有关此标志的更多信息,请参见第 4.10 节“缓存翻译信息”。
  • 内存类型范围寄存器 (MTRR)(在 P6 系列处理器中引入)— 控制在物理内存的特定区域中使用的缓存类型。可以选择第 11.3 节“可用的缓存方法”中描述的任何缓存类型。有关 MTRR 的详细说明,请参见第 11.11 节“内存类型范围寄存器 (MTRR)”。
  • 页属性表 (PAT) MSR(在 Pentium III 处理器中引入)— 扩展了处理器的内存类型功能,以允许逐页分配内存类型(参见第 11.12 节,“页属性表( PAT)”)。
  • 三级缓存禁用标志,IA32_MISC_ENABLE MSR 的第 6 位(仅在基于 Intel NetBurst 微架构的处理器中可用)— 允许禁用和启用 L3 缓存,独立于 L1 和 L2 缓存。
  • KEN# 和WB/WT# 引脚(奔腾处理器)— 允许外部硬件控制用于特定内存区域的缓存方法。它们执行与 P6 系列处理器中的 MTRR 相似(但不完全相同)的功能。
  • PCD 和 PWT 引脚(奔腾处理器)——这些引脚(与控制寄存器 CR3 以及页目录和页表条目中的 PCD 和 PWT 标志相关联)允许在外部 L2 高速缓存中的高速缓存在逐页的基础上,与对这些处理器的 L1 缓存执行的控制一致。 P6 和更新的处理器系列不提供这些引脚,因为 L2 缓存在芯片封装内部。

11.5.2 Precedence of Cache Controls

缓存控制标志和 MTRR 分层运行以限制缓存。 也就是说,如果设置了 CD 标志,则全局阻止缓存(见表 11-5)。 如果清除 CD 标志,则可以使用页面级缓存控制标志和/或 MTRR 来限制缓存。 如果页面级和 MTRR 缓存控制重叠,则阻止缓存的机制具有优先权。 例如,如果 MTRR 使系统内存的某个区域不可缓存,则不能使用页面级缓存控件来为该区域中的页面启用缓存。 反过来也是如此; 也就是说,如果页面级缓存控件将页面指定为不可缓存,则不能使用 MTRR 使页面可缓存。

在将回写和直写缓存策略分配给页面和内存区域的过程中存在重叠的情况下,直写策略优先。写组合策略(只能通过 MTRR 或 PAT 分配)优先于直写或回写。

页级内存类型的选择取决于是否使用 PAT 来选择页的内存类型,如以下部分所述。在基于 Intel NetBurst 微架构的处理器上,可以通过 IA32_MISC_ENABLE MSR 的第 6 位禁用三级缓存。对于这些处理器中的 L3 缓存,使用 IA32_MISC_ENABLE[bit 6] 优先于 CD 标志、MTRR 和 PAT。即当设置了三级缓存禁用标志(cache disabled)时,其他缓存控制对L3缓存没有影响;当标志被清除(启用)时,缓存控制对 L3 缓存的影响与它们对 L1 和 L2 缓存的影响相同。

英特尔酷睿 i7 处理器、基于英特尔酷睿和英特尔凌动微架构的处理器都不支持 IA32_MISC_ENABLE[bit 6]。

11.5.2.1 Selecting Memory Types for Pentium Pro and Pentium Ⅱ Processors

Pentium Pro 和 Pentium II 处理器不支持 PAT。 此处,页的有效存储器类型是通过页的 MTRR 以及页表或页目录条目中的 PCD 和 PWT 位来选择的。 表 11-6 描述了当正常缓存生效时(控制寄存器 CR0 中的 CD 和 NW 标志清零),MTRR 内存类型和页级缓存属性到有效内存类型的映射。 显示为灰色的组合是 Pentium Pro 和 Pentium II 处理器的实现定义。 鼓励系统设计人员避免这些实现定义的组合。


11.5.2.2 Selecting Memory Types for Pentium Ⅲ and More Recent Processor Families

Intel Core 2 Duo、Intel Atom、Intel Core Duo、Intel Core Solo、Pentium M、Pentium 4、Intel Xeon 和 Pentium III 处理器使用 PAT 来选择有效的页面级内存类型。 此处,页面的存储器类型由 MTRR 和 PAT 条目中的值选择,该值通过页表或页目录条目中的 PAT、PCD 和 PWT 位选择(参见第 11.12.3 节,“选择存储器” 从 PAT 输入”)。 表 11-7 描述了当正常缓存生效时(控制寄存器 CR0 中的 CD 和 NW 标志清零),MTRR 存储器类型和 PAT 条目类型到有效存储器类型的映射。

11.5.2.3 Writing Values Across Pages with Different Memory Types

如果内存中两个相邻的页面具有不同的内存类型,并且将一个字或更长的操作数写入跨越这两个页面之间的页面边界的内存位置,则该操作数可能会被写入内存两次。 此操作不会为写入实际内存带来问题; 但是,如果设备映射了分配给页面的内存空间,则设备可能会出现故障。

11.5.3 Preventing Caching

要在启用并收到缓存填充后禁用 L1、L2 和 L3 缓存,请执行以下步骤:

  1. 入无填充缓存模式。 (将控制寄存器 CR0 中的 CD 标志设置为 1,将 NW 标志设置为 0。
  2. 使用 WBINVD 指令刷新所有缓存。
  3. 禁用 MTRR 并将默认内存类型设置为未缓存或为未缓存的内存类型设置所有 MTRR(请参阅第 11.11.2.1 节“IA32_MTRR_DEF_TYPE MSR”中对 TYPE 字段和 E 标志的讨论)。

在设置 CD 标志以确保系统内存一致性后,必须刷新缓存(步骤 2)。如果缓存未刷新,读取时仍会发生缓存命中,并且将从有效缓存行读取数据。

上面列出的三个独立步骤的目的解决了三个不同的要求:(i) 停止用新数据替换缓存中的现有数据 (ii) 确保缓存中的数据被驱逐到内存中,(iii) 确保后续内存引用观察 UC 内存类型语义。缓存控制硬件的不同处理器实现可能允许这三个要求的软件实现的一些变化。请参阅下面的注释。

11.5.4 Disabling and Enabling the L3 Cache

在基于 Intel NetBurst 微架构的处理器上,可以通过 IA32_MISC_ENABLE MSR 的第 6 位禁用三级缓存。 三级缓存禁用标志(IA32_MISC_ENABLE MSR 的第 6 位)允许禁用和启用 L3 缓存,独立于 L1 和 L2 缓存。 在使用此控件禁用或启用 L3 缓存之前,软件应禁用和刷新所有处理器缓存,如前面第 11.5.3 节“防止缓存”中所述,以防止丢失存储在 L3 缓存中的信息。 在禁用或启用 L3 缓存后,可以恢复整个处理器的缓存。

具有 L3 的较新 Intel 64 处理器不支持 IA32_MISC_ENABLE[bit 6],第 11.5.3 节“防止缓存”中描述的过程适用于整个缓存层次结构。

11.5.5 Cache Management Instructions

Intel 64 和 IA-32 体系结构提供了一些用于管理 L1、L2 和 L3 缓存的指令。 INVD 和 WBINVD 指令是特权指令,并作为一个整体对 L1、L2 和 L3 缓存进行操作。 PREFETCHh、CLFLUSH 和 CLFLUSHOPT 指令以及非临时移动指令(MOVNTI、MOVNTQ、MOVNTDQ、MOVNTPS 和 MOVNTPD)提供对缓存的更精细控制,并且可用于所有特权级别。

INVD 和 WBINVD 指令用于使 L1、L2 和 L3 缓存的内容无效。 INVD 指令使所有内部高速缓存条目无效,然后生成一个特殊功能总线周期,指示外部高速缓存也应该无效。应谨慎使用 INVD 指令。它不会强制写回修改后的缓存行;因此,存储在缓存中且未写回系统内存的数据将丢失。除非有特定要求或好处是在不回写修改后的行的情况下使缓存无效(例如,在测试或故障恢复期间,缓存与主存储器的一致性不是问题),软件应该使用 WBINVD 指令。

WBINVD 指令首先写回所有内部高速缓存中的任何修改行,然后使 L1、L2 和 L3 高速缓存的内容无效。它确保高速缓存与主内存的一致性保持不变,而不管有效的写入策略(即,直写或回写)。在此操作之后,WBINVD 指令生成一个(P6 系列处理器)或两个(Pentium 和 Intel486 处理器)特殊功能总线周期,以向外部高速缓存控制器指示应该发生修改后的数据写回,随后外部高速缓存失效。 WBINVD 完成的时间或周期量会因不同缓存层次结构的大小和其他因素而异。因此,WBINVD 指令的使用会对中断/事件响应时间产生影响。

PREFETCHh 指令允许程序向处理器建议将来自系统内存中指定位置的缓存行预取到缓存层次结构中(参见第 11.8 节,“显式缓存”)。

CLFLUSH 和 CLFLUSHOPT 指令允许从内存中清除选定的缓存行。当已知系统内存的缓存部分在不久的将来不会被访问时,这些指令使程序能够显式释放缓存空间。

非临时移动指令(MOVNTI、MOVNTQ、MOVNTDQ、MOVNTPS 和 MOVNTPD)允许将数据从处理器的寄存器直接移动到系统内存中,而不会同时写入 L1、L2 和/或 L3 缓存。这些指令可用于在操作数据时防止缓存污染,这些数据在存储回系统内存之前只修改一次。这些指令对通用、MMX 和 XMM 寄存器中的数据进行操作。

11.5.6 L1 Data Cache Context Mode

L1 数据缓存上下文模式是基于支持英特尔超线程技术的英特尔 NetBurst 微架构的处理器的一项功能。 当 CPUID.1:ECX[bit 10] = 1 时,处理器支持使用 L1 数据缓存上下文模式标志(IA32_MISC_ENABLE[bit 24])设置 L1 数据缓存上下文模式。 可选模式有自适应模式(默认)和共享模式。

BIOS 负责配置 L1 数据缓存上下文模式。

11.5.6.1 Adaptive Mode

自适应模式有助于逻辑处理器之间的 L1 数据缓存共享。 在自适应模式下运行时,L1 数据缓存在同一内核中的逻辑处理器之间共享,如果:

  • 共享缓存的逻辑处理器的 CR3 控制寄存器相同。
  • 共享缓存的逻辑处理器使用相同的分页模式。

在这种情况下,整个 L1 数据缓存可供每个逻辑处理器使用(而不是竞争共享)。

如果共享 L1 数据缓存的逻辑处理器的 CR3 值不同或逻辑处理器使用不同的分页模式,则处理器会竞争缓存资源。 这减少了每个逻辑处理器的缓存的有效大小。 不允许缓存别名(这可以防止数据抖动)。

11.5.6.2 Shared Mode

在共享模式下,L1 数据缓存在逻辑处理器之间竞争共享。 即使逻辑处理器使用相同的 CR3 寄存器和分页模式也是如此。

在共享模式下,L1 数据缓存中的线性地址可以是别名,这意味着缓存中的一个线性地址可以指向不同的物理位置。 解决混叠的机制可能会导致抖动。 因此,IA32_MISC_ENABLE[bit 24] = 0 是基于支持英特尔超线程技术的英特尔 NetBurst 微架构的处理器的首选配置。

11.6 SELF-MODIFYING CODE

写入当前缓存在处理器中的代码段中的内存位置会导致相关的缓存线(或多条线)无效。该检查基于指令的物理地址。此外,P6 系列和奔腾处理器会检查对代码段的写入是否会修改已预取以供执行的指令。如果写入影响预取指令,则预取队列无效。后一种检查基于指令的线性地址。对于 Pentium 4 和 Intel Xeon 处理器,在代码段中写入或窥探指令,其中目标指令已被解码并驻留在跟踪缓存中,会使整个跟踪缓存无效。后一种行为意味着在奔腾 4 和英特尔至强处理器上运行时,自我修改代码的程序会导致性能严重下降。

实际上,对线性地址的检查不应在 IA-32 处理器之间产生兼容性问题。包含自修改代码的应用程序使用相同的线性地址来修改和获取指令。系统软件(例如调试器)可能会使用与用于获取指令的线性地址不同的线性地址来修改指令,将在执行修改后的指令之前执行序列化操作,例如 CPUID 指令,该操作将自动重新同步指令缓存和预取队列。 (有关使用自修改代码的更多信息,请参见第 8.1.3 节,“处理自修改代码和交叉修改代码”。)

对于 Intel486 处理器,写入高速缓存中的指令将在高速缓存中修改它和内存,但如果指令在写入之前被预取,则旧版本的指令可能会被执行。为防止旧指令被执行,请在修改指令的任何写入之后立即编码跳转指令以刷新指令预取单元。

11.7 IMPLICIT CACHING(PENTIUM 4, INTEL XEON, AND P6 FAMILY PROCESSORS)

当一个内存元素被设置为潜在可缓存时,就会发生隐式缓存,尽管该元素可能从未在正常的冯诺依曼序列中被访问过。由于主动预取、分支预测和 TLB 未命中处理,在 P6 和更新的处理器系列上会出现隐式缓存。隐式缓存是现有 Intel386、Intel486 和 Pentium 处理器系统行为的扩展,因为在这些处理器系列上运行的软件也无法确定性地预测指令预取的行为。

为了避免与隐式缓存相关的问题,当缓存一致性机制不会自动处理的可缓存数据发生更改时,操作系统必须显式地使缓存无效。这包括对处理器侦听机制未检测到的双端口或物理别名内存板的写入,以及对内存中页表条目的更改。

例 11-1 中的代码显示了隐式缓存对页表条目的影响。线性地址 F000H 指向物理位置 B000H(F000H 的页表项包含值 B000H),线性地址 F000 的页表项是 PTE_F000。

11.8 EXPLICIT CACHING

Pentium III 处理器引入了四个新指令,即 PREFETCHh 指令,它们为软件提供了对数据缓存的显式控制。这些指令向处理器提供“提示”,即应立即或尽快将 PREFETCHh 指令请求的数据读入缓存层次结构,以备其使用。这些指令提供了提示的不同变体,允许选择将读取数据的缓存级别。

PREFETCHh 指令有助于减少通常与从内存读取数据相关的长延迟,从而有助于防止处理器“停顿”。但是,应谨慎使用这些说明。过度使用会导致资源冲突,从而降低应用程序的性能。此外,这些指令只能用于从内存中预取数据;它们不应用于预取指令。有关正确使用预取指令的更多详细信息,请参阅英特尔® 64 位和 IA-32 架构优化参考手册中的第 7 章“优化缓存使用”。

11.9 INVALIDATING THE TRANSLATION LOOKASIDE BUFFERS(TLBS)

处理器以对软件透明的方式更新其地址转换缓存 (TLB)。 然而,有几种机制允许软件和硬件显式地或作为另一个操作的副作用使 TLB 无效。 大多数细节在第 4.10.4 节“TLB 和分页结构缓存的失效”中给出。 此外,以下操作会使所有 TLB 条目无效,而不管 G 标志的设置如何:

  • 置位或取消置位 FLUSH# 引脚。
  • (仅限奔腾 4、英特尔至强和更高版本的处理器。)写入 MTRR(使用 WRMSR 指令)。
  • 写入控制寄存器CR0 以修改PG 或PE 标志。•(仅限奔腾4、英特尔至强和更高版本的处理器。)写入控制寄存器CR4 以修改PSE、PGE 或PAE 标志。
  • 写入控制寄存器CR4 以将PCIDE 标志从1 更改为0。

有关TLB 的更多信息,请参见第4.10 节“缓存转换信息”。

11.10 STORE BUFFER

Intel 64 和 IA-32 处理器将每次写入(存储)到内存的内容临时存储在存储缓冲区中。存储缓冲器通过允许处理器继续执行指令而不必等到对存储器和/或高速缓存的写入完成来提高处理器性能。它还允许延迟写入以更有效地使用内存访问总线周期。

通常,存储缓冲区的存在对软件是透明的,即使在使用多个处理器的系统中也是如此。处理器确保写入操作始终按程序顺序执行。它还确保在以下情况下始终将存储缓冲区的内容排空到内存中:

  • 生成异常或中断时。
  • (仅限 P6 和更新的处理器系列)执行序列化指令时。
  • 执行I/O 指令时。
  • 执行锁定操作时。
  • (仅限 P6 和更新的处理器系列)执行 BINIT 操作时。
  • (仅限奔腾 III 和更新的处理器系列)使用 SFENCE 指令对存储进行排序时。
  • (仅限奔腾 4 和更新的处理器系列)使用 MFENCE 指令对存储进行排序时。

第 8.2 节“内存排序”中对写排序的讨论详细描述了存储缓冲区的操作。

11.11 MEMORY TYPE RANGE REGISTERS(MTRRS)

以下部分仅适用于 P6 和更新的处理器系列。

内存类型范围寄存器 (MTRR) 提供了一种将内存类型(参见第 11.3 节“可用缓存方法”)与系统内存中的物理地址范围相关联的机制。它们允许处理器优化不同类型存储器的操作,例如 RAM、ROM、帧缓冲存储器和存储器映射 I/O 设备。它们还通过消除早期 IA-32 处理器上用于此功能的存储器控制引脚和驱动它们所需的外部逻辑来简化系统硬件设计。

MTRR 机制允许在物理内存中定义多达 96 个内存范围,并且它定义了一组特定于模型的寄存器 (MSR),用于指定每个范围中包含的内存类型。表11-8显示了可以指定的内存类型及其属性;图 11-4 显示了物理内存与 MTRR 的映射。有关每种内存类型的更详细说明,请参见第 11.3 节“可用缓存的方法”。

硬件复位后,P6 和更新的处理器系列禁用所有固定和可变 MTRR,这实际上使所有物理内存无法缓存。然后,初始化软件应将 MTRR 设置为特定的、系统定义的内存映射。通常,BIOS(基本输入/输出系统)软件会配置 MTRR。然后操作系统或执行程序可以使用正常的页面级缓存属性自由修改内存映射。

在使用 P6 系列或更新系列处理器的多处理器系统中,每个处理器必须使用相同的 MTRR 内存映射,以便软件具有一致的内存视图。

11.11.1 MTRR Feature Identification

MTRR 功能的可用性是特定于模型的。 软件可以通过执行 CPUID 指令并读取特征信息寄存器 (EDX) 中的 MTRR 标志(位 12)的状态来确定处理器是否支持 MTRR。

如果设置了 MTRR 标志(表示处理器实现了 MTRR),则可以从 64 位 IA32_MTRRCAP MSR(对于 P6 系列处理器命名为 MTRRcap MSR)获得有关 MTRR 的附加信息。 IA32_MTRRCAP MSR 是只读 MSR,可以使用 RDMSR 指令读取。 图 11-5 显示了 IA32_MTRRCAP MSR 的内容。 该寄存器中的标志和字段的功能如下:

  • VCNT(可变范围寄存器计数)字段,位 0 到 7 — 指示在处理器上实现的可变范围的数量。
  • FIX(支持固定范围寄存器)标志位 8 — 设置时支持固定范围 MTRR(IA32_MTRR_FIX64K_00000 到 IA32_MTRR_FIX4K_0F8000);清除时不支持固定范围寄存器。
  • WC(写组合)标志位 10 — 设置时支持写组合 (WC) 存储器类型;清除时不支持 WC 类型。
  • SMRR(系统管理范围寄存器)标志,第 11 位 — 设置第 11 位时支持系统管理范围寄存器 (SMRR) 接口;清除时不支持 SMRR 接口。

IA32_MTRRCAP MSR 中的第 9 位和第 12 位至第 63 位被保留。如果软件尝试写入 IA32_MTRRCAP MSR,则会生成通用保护异常 (#GP)。

软件必须读取 IA32_MTRRCAP VCNT 字段以确定可变 MTRR 的数量并查询 IA32_MTRRCAP 中的其他功能位以确定处理器支持的其他功能。例如,某些处理器可能会在 VCNT 字段中报告值“8”,而其他处理器可能会报告具有不同值的 VCNT。

11.11.2 Setting Memory Ranges with MTRRS

内存范围和每个范围中指定的内存类型由三组寄存器设置:IA32_MTRR_DEF_TYPE MSR、固定范围 MTRR 和可变范围 MTRR。 可以分别使用 RDMSR 和 WRMSR 指令读取和写入这些寄存器。 IA32_MTRRCAP MSR 指示这些寄存器在处理器上的可用性(参见第 11.11.1 节,“MTRR 功能标识”)。

11.11.2.1 IA32_MTRR_DEF_TYPE MSR

IA32_MTRR_DEF_TYPE MSR(为 P6 系列处理器命名为 MTRRdefType MSR)设置未包含在 MTRR 中的物理内存区域的默认属性。 该寄存器中的标志和字段的功能如下:

  • 类型字段,位 0 到 7 — 指示用于那些没有 MTRR 为其指定内存类型的物理内存地址范围的默认内存类型(请参阅 该字段的编码见表11-8)。 此字段的合法值为 0、1、4、5 和 6。所有其他值都会导致生成一般保护异常 (#GP)。

    Intel 建议对所有不存在内存的物理内存地址使用 UC(未缓存)内存类型。 要将 UC 类型分配给不存在的内存位置,可以在 Type 字段中将其指定为默认类型,也可以使用固定和可变 MTRR 明确分配。

  • FE(启用固定 MTRR)标志位 10 — 设置时启用固定范围 MTRR;清除时禁用固定范围 MTRR。当启用固定范围 MTRR 时,当发生范围重叠时,它们优先于可变范围 MTRR。如果固定范围 MTRR 被禁用,可变范围 MTRR 仍然可以使用,并且可以映射通常由固定范围 MTRR 覆盖的范围。
  • E(启用 MTRR)标志位 11 — 设置时启用 MTRR;清除时所有 MTRR 都被禁用,并且 UC 内存类型应用于所有物理内存。当设置此标志时,FE 标志可以禁用固定范围 MTRR;当标志清零时,FE 标志没有影响。当设置 E 标志时,默认内存类型字段中指定的类型用于尚未由固定或可变 MTRR 映射的内存区域。

IA32_MTRR_DEF_TYPE MSR 中的第 8 位和第 9 位以及第 12 位至第 63 位被保留;如果软件试图向它们写入非零值,处理器会生成一个通用保护异常 (#GP)。

11.11.2.2 Fixed Range MTRRS

固定内存范围映射到 11 个固定范围寄存器,每个寄存器为 64 位。这些寄存器中的每一个都分为 8 位字段,用于指定寄存器控制的每个子范围的存储器类型:

  • 寄存器 IA32_MTRR_FIX64K_00000 — 映射从 0H 到 7FFFFH 的 512 KB 地址范围。该范围分为八个 64 KB 子范围。
  • 寄存器 IA32_MTRR_FIX16K_80000 和 IA32_MTRR_FIX16K_A0000 — 映射从 80000H 到 BFFFFH 的两个 128 KB 地址范围。该范围分为 16 个 16 KB 子范围,每个寄存器有 8 个范围。
  • 寄存器 IA32_MTRR_FIX4K_C0000 到 IA32_MTRR_FIX4K_F8000 — 映射从 C0000H 到 FFFFFH 的八个 32 KB 地址范围。该范围分为 64 个 4 KB 子范围,每个寄存器有 8 个范围。

固定物理地址范围与固定范围MTRR对应字段的关系如表11-9所示;表 11-8 显示了 MTRR 的存储器类型编码。
对于 P6 系列处理器,固定范围 MTRR 的前缀是 MTRRfix。

11.11.2.3 Variable Range MTRRS

Pentium 4、Intel Xeon 和 P6 系列处理器允许软件为 m 个可变地址范围指定内存类型,为每个范围使用一对 MTRR。 支持的范围数 m 在 IA32_MTRRCAP MSR 的位 7:0 中给出(参见第 11.11.1 节中的图 11-5)。

每对中的第一个条目 (IA32_MTRR_PHYSBASEn) 定义了范围的基地址和内存类型; 第二个条目 (IA32_MTRR_PHYSMASKn) 包含用于确定地址范围的掩码。 “n”后缀在 0 到 m–1 的范围内,用于标识特定的寄存器对。

对于 P6 系列处理器,这些可变范围 MTRR 的前缀是 MTRRphysBase 和 MTRRphysMask。

图 11-7 显示了这些寄存器中的标志和字段。这些标志和字段的功能是:

  • 类型字段,位 0 到 7 — 指定范围的内存类型(有关此字段的编码,请参见表 11-8)。

  • PhysBase 字段,位 12 到 (MAXPHYADDR-1) — 指定地址范围的基地址。在 MAXPHYADDR 为 36 位的情况下,此 24 位值在低端扩展 12 位以形成基地址(这会自动对齐 4 KB 边界上的地址)。

  • PhysMask 字段,位 12 到 (MAXPHYADDR-1) — 指定掩码(如果最大物理地址大小为 36 位,则为 24 位,如果最大物理地址大小为 40 位,则为 28 位)。掩码根据以下关系确定被映射区域的范围:

    — Address_Within_Range AND PhysMask = PhysBase AND PhysMask

    — 该值在低端扩展 12 位以形成掩码值。有关更多信息:请参阅第 11.11.3 节,“示例基础和模板计算”。

    — PhysMask 字段的宽度取决于处理器支持的最大物理地址大小。

    CPUID.80000008H 报告处理器支持的最大物理地址大小。如果 CPUID.80000008H 不可用,软件可能会假设处理器支持 36 位物理地址大小(那么 PhysMask 是 24 位宽,IA32_MTRR_PHYSMASKn 的高 28 位被保留)。请参阅下面的注释。

  • V(有效)标志位 11 — 设置时启用寄存器对;清除时禁用寄存器对。

IA32_MTRR_PHYSBASEn 和 IA32_MTRR_PHYSMASKn 寄存器中的所有其他位都保留; 如果软件试图写入它们,处理器会生成一个通用保护异常 (#GP)。

某些掩码值可能会导致范围不连续。 在此类范围内,未由掩码值映射的区域设置为默认内存类型,除非某个其他 MTRR 为该范围指定了类型。 英特尔不鼓励使用“不连续”范围。

11.11.2.4 System-Management Range Register Interface

如果设置了 IA32_MTRRCAP[bit 11],则处理器支持 SMRR 接口以限制对系统管理模式 (SMM) 软件使用的指定内存地址范围的访问(参见第 34.4.2.1 节)。 如果支持 SMRR 接口,强烈建议 SMM 软件使用它来保护 SMI 处理程序存储在 SMRAM 区域中的 SMI 代码和数据。

系统管理范围寄存器由一对 MSR 组成(见图 11-8)。 IA32_SMRR_PHYSBASE MSR 定义了 SMRAM 内存范围的基地址以及用于在 SMM 中访问它的内存类型。 IA32_SMRR_PHYSMASK MSR 包含一个有效位和一个掩码,用于确定 SMRR 接口保护的 SMRAM 地址范围。 这些 MSR 只能用 SMM 编写; 尝试在 SMM 之外写入它们会导致一般保护异常。

图 11-8 显示了这些寄存器中的标志和字段。 这些标志和字段的功能如下:

  • 类型字段,位 0 到 7 — 指定范围的内存类型(有关此字段的编码,请参见表 11-8)。

  • PhysBase 字段,位 12 到 31 — 指定地址范围的基地址。地址必须小于 4 GBytes,并在 4 KB 边界上自动对齐。

  • PhysMask 字段,位 12 到 31 — 根据以下关系指定确定被映射区域范围的掩码:

    — Address_Within_Range AND PhysMask = PhysBase AND PhysMask

    — 此值在低端扩展 12 位以形成掩码值。有关更多信息:请参阅第 11.11.3 节,“示例基础和模板计算”。

  • V(有效)标志位 11 — 设置时启用寄存器对;清除时禁用寄存器对。

在尝试访问这些 SMRR 寄存器之前,软件必须测试 IA32_MTRRCAP 寄存器中的第 11 位。如果不支持 SMRR,则读取或写入寄存器会导致一般保护异常。

当 IA32_SMRR_PHYSMASK MSR 中的有效标志为 1 时,对指定地址范围的访问处理如下:

  • 如果逻辑处理器在 SMM 中,则访问使用 IA32_SMRR_PHYSBASE MSR 中的内存类型。
  • 如果逻辑处理器不在 SMM 中,则忽略写访问,读访问为每个字节返回一个固定值。在这种情况下使用不可缓存的内存类型 (UC)。

即使指定的地址范围与 MTRR 指定的范围重叠,上述项目也适用。

11.11.3 Example Base and Mask Calculations

本节中的示例适用于支持 36 位最大物理地址大小的处理器。 在可变范围 MTRR 对中输入的基值和掩码值是处理器扩展到 36 位的 24 位值。 例如,要在 IA32_MTRR_PHYSBASE3 寄存器中输入 2 MBytes (200000H) 的基地址,12 个最低有效位将被截断,并在 PhysBase 字段中输入值 000200H。 必须对掩码值执行相同的操作。

例如,要将地址范围从 200000H 映射到 3FFFFFH(2 MB 到 4 MB),则需要 FFFE00000H 的掩码值。 同样,此掩码值的 12 个最低有效位被截断,因此在 IA32_MTRR_PHYSMASK3 的 PhysMask 字段中输入的值是 FFFE00H。 选择此掩码是为了当 200000H 到 3FFFFFH 范围内的任何地址与掩码值进行 AND 运算时,它将返回与基地址与掩码值(即 200000H)进行 AND 运算时相同的值。

要将地址范围从 400000H 映射到 7FFFFFH(4 MB 到 8 MB),在 PhysBase 字段中输入基值 000400H,在 PhysMask 字段中输入掩码值 FFFC00H。

Example 11-2. Setting-Up Memory for a System

以下是为系统设置 MTRR 的示例。 假设系统具有以下特征:

  • 96 MB 的系统内存被映射为回写内存 (WB),以获得最高的系统性能。
  • 自定义的 4 兆字节 I/O 卡映射到基址为 64 兆字节的未缓存内存 (UC)。 此限制迫使 96 MB 的系统内存从 0 到 64 MB 以及从 68 MB 到 100 MB 寻址,从而为 I/O 卡留下 4 MB 的空洞。
  • 8 MB 图形卡被映射到从地址 A0000000H 开始的写组合内存 (WC)。
  • 15 MB 到16 MB 的BIOS 区域映射到UC 内存。

MTRR 的以下设置将为该系统配置生成物理地址空间的正确映射。

此 MTRR 设置使用重叠任何两个内存范围(只要范围映射到 WB 和 UC 内存类型)的能力,以最大限度地减少配置内存环境所需的 MTRR 寄存器的数量。 此设置还满足保留两个寄存器对供操作系统使用的要求。

11.11.3.1 Base and Mask Calculations for Greater-Than 36-bit Physical Address Support

对于支持大于 36 位物理地址大小的 Intel 64 和 IA-32 处理器,软件应查询 CPUID.80000008H 以确定最大物理地址。 请参阅示例。

Example 11-3. Setting-Up Memory for a System with a 40-bit Address Size

如果处理器支持 40 位物理地址大小,则 PhysMask 字段(在 IA32_MTRR_PHYSMASKn 寄存器中)是 28 位而不是 24 位。 对于这种情况,例 11-2 应修改如下:

11.11.4 Range Size and Alignment Requirement

要映射到可变范围 MTRR 的范围必须满足以下“2 的幂”大小和对齐规则:

  1. 最小范围大小为 4 KB,范围的基地址必须至少在 4 KB 边界上。
  2. 对于大于 4 KB 的范围,每个范围的长度必须为 2n,并且其基地址必须在 2n 边界上对齐,其中 n 是等于或大于 12 的值。基地址对齐值不能小于 它的长度。 例如,8 KB 范围不能在 4 KB 边界上对齐。 它必须在至少 8 KB 的边界上对齐。

11.11.4.1 MTRR Precedences

如果未启用 MTRR(通过设置 IA32_MTRR_DEF_TYPE MSR 中的 E 标志),则所有内存访问都是 UC 内存类型。如果启用了 MTRR,则用于内存访问的内存类型确定如下:

  1. 如果物理地址位于物理内存的前 1 MB 内并且启用了固定 MTRR,则处理器使用为适当的固定范围 MTRR 存储的内存类型。
  2. 否则,处理器会尝试将物理地址与可变范围 MTRR 设置的内存类型进行匹配:
    — 如果一个变量内存范围匹配,则处理器使用存储在 IA32_MTRR_PHYSBASEn 寄存器中的内存类型用于该范围。
    — 如果两个或多个变量内存范围匹配且内存类型相同,则使用该内存类型。
    — 如果两个或多个可变内存范围匹配并且其中一种内存类型是 UC,则使用的 UC 内存类型。
    — 如果两个或多个变量内存范围匹配且内存类型为 WT 和 WB,则使用 WT 内存类型。
    — 对于上述规则未定义的重叠,处理器行为未定义。 3. 如果没有匹配的固定或可变内存范围,则处理器使用默认内存类型。

11.11.5 MTRR Initialization

在硬件复位时,P6 和更新的处理器清除可变范围 MTRR 中的有效标志并清除 IA32_MTRR_DEF_TYPE MSR 中的 E 标志以禁用所有 MTRR。 MTRR 中的所有其他位均未定义。

在初始化 MTRR 之前,软件(通常是系统 BIOS)必须将所有固定范围和可变范围 MTRR 寄存器字段初始化为 0。然后软件可以根据已知类型的内存(包括它自动配置的设备上的内存)来初始化 MTRR。 预计在启动操作系统之前进行初始化。 有

关在 MP(多处理器)系统中初始化 MTRR 的信息,请参见第 11.11.8 节“MP 系统中的 MTRR 注意事项”。

11.11.6 Remapping Memory Types

系统设计人员可能会重新映射内存类型以调整性能,或者因为未来的处理器可能无法实现 Pentium 4、Intel Xeon 和 P6 系列处理器支持的所有内存类型。以下规则支持一致的内存类型重新映射:

  1. 不应将内存类型映射到具有较弱内存排序模型的另一种内存类型。例如,不可缓存类型不能映射到任何其他类型,回写、直写和写保护类型不能映射到弱排序写组合类型。
  2. 不延迟写入的内存类型不应映射到延迟写入的内存类型,因为此类内存类型的应用程序可能依赖其直写行为。因此,回写类型不能映射到直写类型。
  3. 认为写数据不一定被后续读取存储和读回的内存类型,例如写保护类型,只能映射到具有相同行为的另一种类型(奔腾 4 没有其他类型) 、英特尔至强和 P6 系列处理器)或不可缓存类型。

在许多特定情况下,系统设计人员可以获得有关如何使用内存类型的附加信息,从而允许进行附加映射。例如,没有关联写副作用的直写存储器可以映射到回写存储器。

11.11.7 MTRR Maintenance Programming Interface

操作系统在启动后维护 MTRR,并为内存映射设备设置或更改内存类型。 操作系统应提供驱动程序和应用程序编程接口 (API) 来访问和设置 MTRR。 函数调用 MemTypeGet() 和 MemTypeSet() 定义了这个接口。

11.11.7.1 MemTypeGet() Function

MemTypeGet() 函数返回参数 base 和 size 指定的物理内存范围的内存类型。 基地址是起始物理地址,大小是内存范围的字节数。 该函数自动将基地址和大小与 4 KB 边界对齐。 MemTypeGet() 函数的伪代码在例 11-4 中给出。

如果处理器不支持 MTRR,则该函数返回 UNSUPPORTED。 如果未启用 MTRR,则返回 UC 内存类型。 如果多个内存类型对应于指定范围,则返回 MIXED_TYPES 状态。 否则,返回为范围定义的内存类型(UC、WC、WT、WB 或 WP)。

例 11-5 中 Get4KMemType() 函数的伪代码获取给定物理地址上单个 4 KB 范围的内存类型。 示例代码通过将地址与已知固定范围进行比较来确定 PHY_ADDRESS 是否在固定范围内:0 到 7FFFFH(64 KB 区域)、80000H 到 BFFFFH(16 KB 区域)和 C0000H 到 FFFFFH(4 KB 区域) 地区)。 如果地址落在这些范围之一内,则其 MTRR 之一中的相应位将确定存储器类型。

11.11.7.2 MemTypeSet() Function

例 11-6 中的 MemTypeSet() 函数将参数 base 和 size 指定的物理内存范围的 MTRR 设置为 type 指定的类型。 基地址和大小是 4 KB 的倍数,大小不为 0。


MemTypeSet 函数中的物理地址到变量范围映射算法通过循环访问当前变量范围寄存器并确定相关物理地址是否与任何当前范围匹配来检测与当前变量范围寄存器的冲突。在此扫描期间,该算法可以检测是否有任何当前变量范围重叠并可以连接成单个范围。

pre_mtrr_change() 函数在更改 MTRR 之前禁用中断,以避免执行具有部分有效 MTRR 设置的代码。该算法通过设置 CD 标志并清除控制寄存器 CR0 中的 NW 标志来禁用缓存。使用 WBINVD 指令使缓存无效。该算法通过清除控制寄存器 CR4 中的页面全局启用 (PGE) 标志(如果 PGE 已经设置)或通过更新控制寄存器 CR3(如果 PGE 已经清除)来刷新所有 TLB 条目。最后,它通过清除 IA32_MTRR_DEF_TYPE MSR 中的 E 标志来禁用 MTRR。

更新内存类型后,post_mtrr_change() 函数会重新启用 MTRR,并再次使缓存和 TLB 无效。由于处理器对指令和数据的积极预取,因此需要第二次无效。该算法通过设置 CD 标志来恢复中断并重新启用缓存。

操作系统可以批量处理多个 MTRR 更新,以便只发生一对缓存失效。

11.11.8 MTRR Considerations in MP Systems

在 MP(多处理器)系统中,操作系统必须保持系统中所有处理器之间的 MTRR 一致性。 Pentium 4、Intel Xeon 和 P6 系列处理器不提供硬件支持来保持这种一致性。通常,所有处理器必须具有相同的 MTRR 值。

这个要求意味着当操作系统初始化一个 MP 系统时,它必须加载引导处理器的 MTRR,而寄存器 MTRRdefType 中的 E 标志为 0。然后操作系统指示其他处理器使用相同的内存映射加载它们的 MTRR。在所有处理器都加载了它们的 MTRR 之后,操作系统会向它们发出信号以启用它们的 MTRR。屏障同步用于防止进一步的内存访问,直到所有处理器都指示启用了 MTRR。这种同步很可能是一种击落式算法,具有共享变量和处理器间中断。

MP 系统中 MTRR 值的任何更改都需要操作系统重复加载和启用过程以保持一致性,使用以下过程:

  1. 向所有处理器广播以执行以下代码序列。
  2. 禁用中断。
  3. 等待所有处理器到达此点。
  4. 进入无填充缓存模式。 (将控制寄存器 CR0 中的 CD 标志设置为 1,将 NW 标志设置为 0。)
  5. 使用 WBINVD 指令刷新所有高速缓存。注意在支持self-snooping、CPUID特性标志位27的处理器上,这一步是不必要的。
  6. 如果在控制寄存器 CR4 中设置了 PGE 标志,则通过清除该标志来刷新所有 TLB。
  7. 如果控制寄存器 CR4 中的 PGE 标志被清除,则通过执行从控制寄存器 CR3 到另一个寄存器的 MOV,然后从该寄存器返回到 CR3 的 MOV 来刷新所有 TLB。
  8. 禁用所有范围寄存器(通过清除寄存器 MTRRdefType 中的 E 标志)。如果仅修改变量范围,软件可能会清除受影响的寄存器对的有效位。
  9. 更新 MTRR。
  10. 启用所有范围寄存器(通过设置寄存器 MTRRdefType 中的 E 标志)。如果只修改了可变范围寄存器并且清除了它们各自的有效位,则改为设置受影响范围的有效位。
  11. 第二次刷新所有缓存和所有 TLB。 (奔腾 4、英特尔至强和 P6 家族处理器需要 TLB 刷新。使用奔腾 4、英特尔至强和 P6 家族处理器时不需要执行 WBINVD 指令,但在未来的系统中可能需要。)
    12.进入正常缓存模式重新启用缓存。 (将控制寄存器 CR0 中的 CD 和 NW 标志设置为 0。)
  12. 设置控制寄存器 CR4 中的 PGE 标志,如果在步骤 6(以上)中被清除。
  13. 等待所有处理器到达此点。
  14. 启用中断。

11.11.9 Large Page Size Considerations

MTRR 为有限数量的具有 4 KB 粒度(与 4 KB 页的粒度相同)的区域提供内存类型。给定页面的内存类型缓存在处理器的 TLB 中。使用大页面(2 MBytes、4 MBytes 或 1 GBytes)时,单个页表条目涵盖多个 4 KB 颗粒,每个颗粒具有单一内存类型。由于大页面的内存类型缓存在 TLB 中,如果大页面映射到 MTRR 已与多种内存类型映射的内存区域,则处理器可能会以未定义的方式运行。

通过确保一个大页面内的所有 MTRR 内存类型范围都是相同的类型,可以避免未定义的行为。如果大页面映射到包含不同 MTRR 定义的内存类型的内存区域,则应为该范围内最保守的内存类型设置页表条目中的 PCD 和 PWT 标志。例如,用于内存映射 I/O 和常规内存的大页面被映射为 UC 内存。或者,操作系统可以使用多个 4 KB 页面映射区域,每个页面都有自己的内存类型。

大页面中的所有 4 KB 范围都具有相同内存类型的要求意味着具有不同内存类型的大页面可能会遭受性能损失,因为它们必须使用最低公分母内存类型进行标记。相同的考虑适用于 1 GByte 页面,每个页面可能包含多个 2 MB 范围。
Pentium 4、Intel Xeon 和 P6 系列处理器为 0 到 4 MB 的物理内存范围提供特殊支持,这可能由固定和可变 MTRR 映射。

当 Pentium 4、Intel Xeon 或 P6 系列处理器检测到大页面与此内存范围的前 1 MB 重叠且内存类型与固定 MTRR 冲突时,将调用此支持。此处,处理器将存储器范围映射为 TLB 内的多个 4 KB 页。此操作以性能为代价确保正确的行为。为了避免这种性能损失,操作系统软件应该为地址大于或等于 4 MB 的内存区域保留大页面选项。

11.12 PAGE ATTRIBUTE TABLE(PAT)

页属性表 (PAT) 扩展了 IA-32 体系结构的页表格式,允许基于线性地址映射将内存类型分配给物理内存区域。 PAT 是 MTRR 的配套功能; 也就是说,MTRR 允许将内存类型映射到物理地址空间的区域,其中 PAT 允许将内存类型映射到线性地址空间内的页面。 MTRR 可用于静态描述物理范围的内存类型,通常由系统 BIOS 设置。 PAT 扩展了页表中 PCD 和 PWT 位的功能,以允许可以用 MTRR 分配的所有五种存储器类型(加上一种附加存储器类型)也可以动态分配给线性地址空间的页面。

PAT 被引入到奔腾 III 处理器上的 IA-32 架构。 它也适用于 Pentium 4 和 Intel Xeon 处理器。

11.12.1 Detecting Support for the PAT-Feature

操作系统或执行程序可以通过执行 EAX 寄存器中值为 1 的 CPUID 指令来检测 PAT 的可用性。 对 PAT 的支持由 PAT 标志(返回到 EDX 寄存器的值的第 16 位)指示。 如果支持 PAT,操作系统或执行程序可以使用 IA32_PAT MSR 对 PAT 进行编程。 将内存类型分配给 PAT 中的条目后,软件可以使用页表和页目录条目中的 PAT 索引位 (PAT) 以及 PCD 和 PWT 位将内存类型从 PAT 分配到 个别页面。

请注意,在任何启用 PAT 的控制寄存器中都没有单独的标志或控制位。 在所有支持它的处理器上始终启用 PAT,并且在所有分页模式下,只要启用分页,就会始终进行表查找。

11.12.2 IA32_PAT MSR

IA32_PAT MSR 位于 MSR 地址 277H(请参阅英特尔® 64 和 IA-32 架构软件开发人员手册,第 4 卷中的第 2 章“模型特定寄存器 (MSR)”)。 图 11-9。 显示了 64 位 IA32_PAT MSR 的格式。

IA32_PAT MSR 包含八个页面属性字段:PA0 到 PA7。 每个字段的三个低位用于指定内存类型。 每个字段的五个高位是保留的,必须设置为全 0。 八个页面属性字段中的每一个都可以包含表 11-10 中指定的任何内存类型编码。

11.12.3 Selecting a Memory Type from the PAT

要从 PAT 中为页面选择内存类型,必须在页面的页表或页目录条目中编码由 PAT、PCD 和 PWT 位组成的 3 位索引。 表 11-11 显示了 PAT、PCD 和 PWT 位的可能编码以及每种编码选择的 PAT 条目。 PAT 位是指向 4 KB 页面的页表条目中的第 7 位和指向更大页面的分页结构条目中的第 12 位。 PCD 和 PWT 位分别是指向任意大小页面的分页结构条目中的第 4 位和第 3 位。

为页面选择的 PAT 条目与页面映射到的物理内存区域的 MTRR 设置结合使用,以确定页面的有效内存类型,如表 11-7 所示。

11.12.4 Programming the PAT

表 11-12 显示了处理器上电或复位后每个 PAT 条目的默认设置。 软复位(INIT 复位)后设置保持不变。

通过使用 WRMSR 指令写入 IA32_PAT MSR,可以更改 PAT 的所有条目中的值。 IA32_PAT MSR 可对在 CPL 为 0 的 CPL 下运行的软件进行读写访问(分别使用 RDMSR 和 WRMSR 指令)。表 11-10 显示了 PAT 中条目的允许编码。尝试将未定义的内存类型编码写入 PAT 会导致生成一般保护 (#GP) 异常。

操作系统负责确保对 PAT 条目的更改以维护处理器缓存和转换后备缓冲区 (TLB) 的一致性的方式发生。这是通过遵循第 11.11.8 节“MP 系统中的 MTRR 注意事项”中指定的过程来完成的,用于更改多处理器系统中的 MTRR 值。它需要特定的操作序列,包括刷新处理器缓存和 TLB。

PAT 允许在页表中指定任何内存类型,因此可以将单个物理页映射到两个或多个不同的线性地址,每个地址具有不同的内存类型。 Intel 不支持这种做法,因为它可能会导致未定义的操作,从而导致系统故障。特别是,WC 页面绝不能被称为可缓存页面,因为 WC 写入可能不会检查处理器缓存。

将先前映射为可缓存内存类型的页面重新映射到 WC 页时,操作系统可以通过执行以下操作来避免这种类型的别名:

  1. 在页表中删除先前映射到可缓存内存类型的页面;也就是说,让它们不存在。
  2. 刷新可能使用了映射的处理器的 TLB,甚至是推测性的。
  3. 使用新的内存类型创建到相同物理地址的新映射,例如 WC。
  4. 刷新之前可能使用过映射的所有处理器上的缓存。注意在支持self-snooping的处理器上,CPUID特性标志位27,这一步是不必要的。

使用页目录作为页表(以映射大页)并启用页大小扩展的操作系统必须仔细检查 PAT 索引位对 4 KB 页表条目的使用。页表项的 PAT 索引位(位 7)对应于页目录项中的页大小位。因此,操作系统在为也用作页目录的页表设置缓存类型时,只能使用 PAT 条目 PA0 到 PA3。如果操作系统在将此内存用作页表时尝试使用 PAT 条目 PA4 到 PA7,它会有效地设置 PS 位以访问此内存作为页目录。

为了与不支持 PAT 的早期 IA-32 处理器兼容,应注意选择 PAT 中条目的编码(请参阅第 11.12.5 节,“PAT 与早期 IA-32 处理器的兼容性”)。

11.12.5 PAT Compatibility with Earlier IA-32 Processors

对于支持 PAT 的 IA-32 处理器,IA32_PAT MSR 始终处于活动状态。也就是说,PCD 和 PWT 位在
页表条目和页目录条目(指向页面)总是通过选择 PAT 中的条目来间接为页面选择内存类型。它们从不直接为页面选择内存类型,因为它们在没有实现 PAT 的早期 IA-32 处理器中所做的(见表 11-6)。

为了让编写的代码兼容在不支持 PAT 的早期 IA-32 处理器上运行,PAT 机制被设计为允许向后兼容早期处理器。这种兼容性是通过 3 位 PAT 条目索引中 PAT、PCD 和 PWT 位的排序提供的。对于没有实现 PAT 的处理器,PAT 索引位(页表条目中的第 7 位和页目录条目中的第 12 位)被保留并设置为 0。在保留 PAT 位的情况下,只有前四个条目可以通过 PCD 和 PWT 位选择 PAT 的数量。在上电或复位时(见表 11-12),前四个条目被编码以选择与 PCD 和 PWT 位通常在未实现 PAT 的 IA-32 处理器中直接选择相同的存储器类型。因此,如果 PAT 中前四个条目的编码在上电或复位后保持不变,则编写为在未实现 PAT 的早期 IA-32 处理器上运行的代码将在实现了 PAT 的 IA-32 处理器上正确运行PAT。

【Manual】Memory Cache Control相关推荐

  1. 【Paper】2015_El H_Decentralized Control Architecture for UAV-UGV Cooperation

    Decentralized Control Architecture for UAV-UGV Cooperation 1 Introduction 2 Problem Statement and Ar ...

  2. 【LeetCode】LRU Cache 解决报告

    插话:只写了几个连续的博客,博客排名不再是实际"远在千里之外"该.我们已经进入2一万内. 再接再厉.油! Design and implement a data structure ...

  3. 【Guava】Guava Cache的refresh和expire刷新机制

    1.概述 转载:https://www.cnblogs.com/liuxiaochong/p/13613071.html 总览参考:[Guava]Google Guava本地高效缓存 案例参考:[gu ...

  4. 【转载】Java Cache系列之Cache概述和Simple Cache

    原文地址:http://www.blogjava.net/DLevin/archive/2013/10/15/404770.html 前记:最近公司在做的项目完全基于Cache(Gemfire)构建了 ...

  5. 【Paper】2019_Bearing-only circumnavigation control of the multi-agent system around a moving target

    Yu Y, Li Z, Wang X, et al. Bearing-only circumnavigation control of the multi-agent system around a ...

  6. 【Paper】2019_Distributed Cooperative Control of a High-speed Train

    2019_Distributed Cooperative Control of a High-speed Train 文章目录 1. Introduction 2. Modeling of a hig ...

  7. 【Paper】2015_Active fault-tolerant control system design with trajectory re-planning against actuator

    Chamseddine A, Theilliol D, Zhang Y M, et al. Active fault‐tolerant control system design with traje ...

  8. 【Paper】2019_Distributed Optimal Control of Energy Storages in a DC Microgrid with Communication Dela

    M. Shi, X. Chen, J. Zhou, Y. Chen, J. Wen and H. He, "Distributed Optimal Control of Energy Sto ...

  9. 【Paper】2010_Distributed optimal control of multiple systems

    Dong W. Distributed optimal control of multiple systems[J]. International Journal of Control, 2010, ...

最新文章

  1. 众所周知,static修饰的成员只实例化一次,而string类型每次赋值都会重新创建一个实例,那么用static修饰string呢?...
  2. LaTeX 的对参考文献的处理
  3. 13_短信发送器_问题说明
  4. 最长公共子序列-dp
  5. 狂赌智能手机 中国互联网巨头深陷零利润困局
  6. 推荐北大饶毅教授的《生物学概念与途径》课程(慕课视频+讲义)
  7. 工作日志20150202
  8. 使用命令行编译Less源文件
  9. 对double值进行四舍五入,保留两位小数的几种方法
  10. [转载] python中实现矩阵乘法
  11. Windows10下鼠标跳屏问题——Microsoft Serial Ballpoint
  12. [Android]OpenGL绘制2D几何图形
  13. POJ 2525 Text Formalization 笔记
  14. Java 原生 PCM 格式文件转 WAV
  15. 个人所得税 java_计算个人所得税的java代码
  16. 错过“复联4”在所不惜,迅雷链技术沙龙北京站有哪些更精彩的地方?
  17. js 点击文本框,预览选择图片
  18. 海乐淘商城系统--01前缀(功能介绍以及关于架构)
  19. vue 判断两对象是否一致_判断两个对象的值是否相等
  20. 4_树莓派机载计算机的机器视觉样例教程——无名创新

热门文章

  1. python爬虫课程设计过程_[Python]新手写爬虫全过程(已完成)
  2. matlab滤波器设计双陷滤波,基于MATLAB 双线性变换法IIR 滤波器的设计
  3. 服务器无法用u盘安装系统安装win7系统安装不了怎么办,为什么新电脑不支持安装Win7操作系统?...
  4. C陷阱与缺陷--笔记
  5. 【Java专题】Java泛型集合详解
  6. 二手书交易平台相关调研
  7. go - rune类型
  8. python编程:从入门到实践习题第五章5-8~5-11
  9. PaddleClas-图像分类中的8种数据增广方法(cutmix, autoaugment,..)
  10. C语言中的feof函数