ARMv8中将内存分为两种类型:Normal memory和Device memory,Normal memory适用于系统中的大部分内存,而Device memory则适用于外设所使用的内存。
1. Normal Memory
Normal memory类型属性适用于系统中的大多数内存。它表示架构允许硬件对这些位置执行推测数据读取访问(Speculative data read accesses),而不管这些位置的访问权限如何。为了确保访问Normal memory是的顺序性,有必要使用内存屏障指令:DMB 。
1.1 Shareable Normal Memory
一个Normal 内存地址可以具有以下一种 Shareability 属性:
Inner Shareable, 适用于Inner Inner Shareable shareability 区域。
Outer Shareable, 适用于Inner Shareable and the Outer Shareable shareability 区域。
Non-shareable.
1.1.1 Inner Shareable, and Outer Shareable属性
ARM 架构将系统抽象成一系列 Inner和Outer 可共享属性区域。
每个Inner共享域包含一组观察者(observers),这些观察者对于该组中的每个成员都是数据一致的,用于使用该组中的任何成员所创建的内部共享属性(Inner Shareable attribute)进行数据访问。
每个Outer共享域包含一组观察者,这些观察者对于该组的每个成员都是数据一致的,用于使用该组的任何成员所创建的外部共享属性(Outer Shareable attribute)进行数据访问。
同样具有以下属性:
每个观察者只是一个内部共享域的成员。
每个观察者只能是单个外部共享域的成员。
内部可共享域中的所有观察者总是同一外部可共享域的成员。
这意味着内部共享性域是外部共享性域的一个子集,尽管它不需要是一个合适的子集。
因为对Non-cacheable位置的所有数据访问,对所有观察者来说都是数据一致的,所以Non-cacheable位置总是被视为外部共享的(Outer Shareable)。内部共享域预期是由单个hypervisor或操作系统控制的PE的集合。
如果一个系统中存在两个处理器簇(cluster),则必须保证:
在每个簇中,处理器的data caches和unified caches对所有带有Inner Shareable属性的内存位置的数据访问,均是透明的。
然而,在两个簇之间,如果仅仅是Inner Shareable属性,caches在数据访问中不需被要求保持一致性。如果是Outer Shareable属性,则要求保持数据一致性。
在这样一个系统中,对于Inner Shareable 属性,每个cluster处于不同的shareability 区域,但是对于Outer Shareable属性,子系统中的所有组件均在同一个shareability区域。
一个系统可能实现两个这样的子系统,如果其中一个子系统的data cache和unified cache均对其他子系统中访问不透明,那么这个系统就有两个Outer shareable 区域。
对于可共享的普通内存(shareable Normal memory),Load-Exclusive和Store-Exclusive指令考虑了同一共享域中多个观察者(多个core)访问的可能性。
1.2 Non-shareable Normal memory
对于Normal 内存区域,不可共享的normal内存是一块只能被单个CPU访问的Normal内存。Non-shareable的Normal内存不要求硬件保证多个观察者数据访问的一致性,除非该内存是不可缓存的(Non-cacheable)。
对于Non-shareable内存,如果其他观察者共享这个内存系统,软件必须使用缓存维护相关指令,来保证在多个观察者之间数据通信的缓存一致性问题。此外也需要额外的内存屏障操作来保证内存的处理顺序。
此外,对于Non-shareable内存,是否支持Load-Exclusive和Store-Exclusive指令中考虑了多个观察者访问的可能性,这个由具体的实现定义IMPLEMENTATION DEFINED。
1.3 Cacheability attributes for Normal memory
除了Outer Shareable, Inner Shareable 和 Non-shareable属性外,每个Normal 内存还被分配了一个缓存属性:
Write-Through Cacheable.Write-Back Cacheable.
Non-cacheable.
缓存属性为位于内存区域共享域之外的观察者提供了一种一致性控制机制。在某些情况下,与使用硬件一致性机制或使用缓存维护的程序相比,使用Write-Through cache或non -cacheable区域可能提供更好的机制来控制一致性。为此,架构要求non -cacheable或Write-Through缓存内存具有以下属性:
观察者访问某一级缓存内的内存系统时,对该级缓存的Write-Through cache或non -cacheable的内存位置的完整写入,对于所有访问该一级缓存外的内存系统的观察者来说都是可见的,而不需要显式的缓存维护。
由访问某个level cache之外的内存系统的观察者,所完成的对该级别cache的Non-cacheable
的内存位置的写入,对于访问该级cache内部的内存系统的所有观察者来说都是可见的,而不需要显式的缓存维护。
对于Non-cacheable的普通内存的访问,DMB指令在对单个外设或IMPLEMENTATION DEFINED大小的内存块的所有访问上引入一个Barrier-ordered-before关系。
对于普通内存,Arm架构提供了缓存属性,这些属性是为缓存的两个概念级别(内部缓存和外部缓存,the inner and the outer cache)独立定义的。这些概念级缓存和实现的物理级缓存之间的关系是IMPLEMENTATION DEFINED的,并且可以区别于内部和外部共享域之间的边界,但是:
Inner是指最内层的缓存,即最接近PE的缓存,并且总是包括最低级别的缓存。
由Inner缓存属性控制的缓存不能位于由Outer缓存属性控制的缓存之外。
在具体的实现中可能没有outer 缓存。比如有L1,L2, L3的三级缓存架构中,三个缓存可能都是inner缓存,而不存在outer缓存。也可以是L1是inner缓存,L2和L3是outer缓存。
资料直通车:Linux内核源码技术学习路线+视频教程内核源码
2. Device Memory
Device内存类型属性定义了内存位置,其中对该位置的访问可能导致副作用,或者加载返回的值可能根据执行的加载数量而变化。通常,Device内存属性用于内存映射的外设(memory-mapped peripherals)和类似的位置。
device内存区域通常是给一些外设,比如USB uart之类的模块用的,首先是non-cacheable的,也就是不能走cache,直接访问内存,数据只存在内存中,其他地方没有备份,这样可以保证数据的唯一性,准确性。其次,外设的内存交互一般对时间(timing)的要求较高,所以也需要在有限的时间内完成读写操作。还有就是除了不走cache之外,访问device 内存可能也没有其他的内存访问上的优化,比如推测性访问。总而言之,就是给外设用的内存属性,外设的内存交互需要满足:及时,高效,准确:
不允许对具有任何Device memory属性的任何内存位置进行推测性数据访问(Speculative data accesses)。这意味着对任何Device内存类型的每个内存访问都必须是由程序的简单顺序执行生成的。
对任何Device memory类型的内存位置的写入在有限时间内完成。
如果从Device memory类型的内存位置读取的返回值发生了变化,而观察者没有显式的内存写入影响,则该变化也必须在有限时间内对系统中的所有观察者进行全局观察。这样的更改可能发生在保存状态信息的外设(peripheral location that holds status information)。
对于系统中的所有观察者来说,对Device memory位置的数据访问都是一致的,并相应地被视为可外部共享的(Outer Shareable)。
具有任何Device memory属性的内存位置都不能分配到缓存中。
对于任何Device memory类型的访问,使用DMB指令,在对单个外设或指定大小的内存块的所有访问上引入一个Barrier-ordered-before关系。
如果内存位置不能支持未对齐的内存访问(unaligned memory accesses),那么对该内存位置的未对齐访问将在转换的第一阶段生成对齐错误(Alignment fault),该转换将该位置定义为Device。
硬件不会阻止从具有任何Device memory属性的内存位置进行推测性的指令获取,除非该内存位置也被标记为所有异常级别的execute-never。
原文作者:Arm精选