草庐IT

AArch32/AArch64系统级内存模型(三)

BSP-路人甲 2023-03-28 原文

1. 内存系统架构

1.1 系统级存储系统体系结构的形式

  Armv8的a -profile体系结构包括一个虚拟内存系统体系结构(Virtual Memory System Architecture - VMSA),参见----。

1.2 系统级可见 内存属性

类型 说明
Normal 这通常用于大容量内存操作,包括读/写和只读操作。系统中大部分内存都是这种类型
Device 对该种类型的内存进行读写可能具有连带效应(side-effects,指对一个内存位置的读写操作会影响其它内存位置)或者从该种内存中的一个位置装载的值可能随着装载的次数而变化。通常内存映射外设(指使用访问内存的方法来访问的外设)会采用这种内存类型

(1) 上表中Shareability是与一致性有关的内存属性, 用来指示一个内存位置对于一些处理器是否是可共享的。共享意味着需要硬件保证一个内存位置中的内容对一定范围内可访问该位置的多个处理器是一致。参见:Cache的相关知识(一) - 9. 共享域
(2) cacheability是指cache的回写策略。参见:Cache的相关知识(一) - 8.2 cache的回写策略


2. 对混合字节序的支持

如果在AArch32异常级别上实现了混合字节序支持,则字节序由PSTATE.E控制。 对于异常返回AArch32状态,将从SPSR_ELx.E复制PSTATE.E。 如果目标异常级别仅支持小端访问,则SPSR_ELx.E为RES0。 如果目标异常级别仅支持大端访问,则SPSR_ELx.E为RES1。

1. AArch64 显式数据访问和转换表遍历的endianness

2. AArch32 显式数据访问和转换表遍历的endianness

注意
(1) 如果使用AArch32为异常级别实现了混合字节序支持,则字节序由PSTATE.E控制。 当异常从AArch64状态返回到AArch32状态,将从SPSR_ELx.E复制PSTATE.E。

(2) 如果目标异常级别仅支持小端访问,则SPSR_ELx.E为RES0。 如果目标异常级别仅支持大端访问,则SPSR_ELx.E为RES1。 PSTATE.E在AArch64状态下被忽略。


3. 对缓存的支持

3.1 缓存标识

Armv8缓存标识由一组寄存器组成,这些寄存器描述了缓存操作指令将如何影响在PE上的应用的缓存。包括

类型 AArch64 AArch32
影响整个缓存 例如:IC IALLU(Instruction Cache Invalidate All to PoU) 例如:ICIALLUIS(Instruction Cache Invalidate All to PoU, Inner Shareable)
VA操作 例如: IC IVAU (Instruction Cache line Invalidate by VA to PoU) 例如:ICIALLUIS (Instruction Cache line Invalidate by VA to PoU)
way(路)/set(组)操作 例如: DC ISW (Data or unified Cache line Invalidate by Set/Way) 例如:ICIALLUIS (Data Cache line Invalidate by Set/Way)

缓存标识寄存器有:

寄存器类型 AArch64寄存器名称 AArch32寄存器名称 说明
Cache Type Register) CTR_EL0 CTR 该寄存器定义了
(1) 受指令缓存操作指令影响的任何指令缓存的最小行长度;
(2) 受数据缓存操作指令的影响的任何数据或统一性缓存的最小行长度;
(3) 一级指令缓存的缓存索引和标记策略。
Cache Level ID Register CLIDR_EL1 CLIDR 该寄存器定义了
(1) 缓存类型;
(2) Level of Unification Inner Shareable (LoUIS), Level of Coherence (LoC) and the Level of Unification (LoU) ;
(3) 一个可选的ICB字段,用于指示内部缓存可缓存内存区域与外部缓存可缓存区域之间的边界
Cache Size Selection Register CSSELR_EL1 CSSELR 该寄存器定义了
(1) 选择当前缓存的缓存级别(Level 1 ~ Level 7);
Cache Size Identification Register CCSIDR_EL1 当应用FEAT_CCIDX时:
CCSIDR/ CCSIDR2

当未应用FEAT_CCIDX时:
CCSIDR
该寄存器主要提供有关当前选定缓存的体系结构的信息,比如NumSets, Associativity, and LineSize;

3.2 Cacheability, cache allocation hints, and cache transient hints

可缓存性 仅适用于normall类型的内存,并为内部和外部缓存位置单独定义。所有device类型的设备内存总是被视为不可缓存的。内存属性Cacheability表示一个内存位置是否可以被分配到缓存中。

内存属性包括一个可缓存属性,参见:8.2 cache的回写策略

3.3 启用和禁用内存访问的缓存

在Armv8中,可缓存性控制字段可以强制所有具有Normal内存类型的内存位置被视为不可缓存,而不管它们的可缓存性属性是什么。每一阶段的地址转换都有独立的控制:

  • 数据访问。这些控件也适用于对 translation tables 的访问。
  • 指令访问。

3.3.1在AArch64状态下,可缓存性控制字段及其效果如下

translation regime Non-secure/secure 寄存器 说明
EL1&0 - SCTLR_EL1.C == 0 (1) 访问的内存数据在所有stage1转换都是 Non-cacheable
(2) 对stage1转换表的访问是 Non-cacheable
EL1&0 - SCTLR_EL1.I == 0 (1) 访问内存时的指令在所有stage1转换都是 Non-cacheable
EL1&0 - HCR_EL2.CD == 1 (1) 访问的内存数据在stage2转换都是 Non-cacheable
(2) 对stage2转换表的访问是 Non-cacheable
EL1&0 - HCR_EL2.ID == 1 (1) 访问内存时的指令在所有stage2转换都是 Non-cacheable
EL1&0 - HCR_EL2.DC == 1 (1) 所有 stage1转换和对stage1转换表的所有访问都被视为对 Non-shareable Inner Write-Back Cacheable Read-Allocate Write-Allocate, Outer Write-Back Cacheable Read-Allocate Write-Allocate memory的内存进行访问,无论 SCTLR_EL1.{I, C}的值如何,这适用于数据和指令访问的转换
EL1&0 - SCTLR_EL1.M == 0 禁用了stage1 的translations ,并且HCR_EL2.DC的值为0
(1) 如果 SCTLR_EL1.I的值为0,从stage1访问内存的指令是 Outer Shareable, Inner Non-cacheable, Outer Non-cacheable
(2) 如果 SCTLR_EL1.I的值为1,从stage1访问内存的指令是 Outer Shareable, Inner Write-Through cacheable, Outer Write-Through cacheable
EL2 - SCTLR_EL2.C == 0 (1) 访问的内存数据都是 Non-cacheable
(2) 对转换表的访问是 Non-cacheable
EL2 - SCTLR_EL2.I == 0 (1) 访问内存时的指令都是 Non-cacheable
EL2&0 - SCTLR_EL2.C == 0 (1) 访问的内存数据都是 Non-cacheable
(2) 对转换表的访问是 Non-cacheable
EL2&0 - SCTLR_EL2.I == 0 (1) 访问内存时的指令都是 Non-cacheable
EL3 - SCTLR_EL3.C == 0 (1) 访问的内存数据都是 Non-cacheable
(2) 对EL2转换表的访问是 Non-cacheable
EL3 - SCTLR_EL3.I == 0 (1) 访问内存时的指令都是 Non-cacheable
!(EL1&0) - SCTLR_ELx.M == 0 禁用了stage1 的translations ,并且HCR_EL2.DC的值为0
(1) 如果 SCTLR_ELx.I的值为0,从stage1访问内存的指令是 Outer Shareable, Inner Non-cacheable, Outer Non-cacheable
(2) 如果 SCTLR_ELx.I的值为1,从stage1访问内存的指令是 Outer Shareable, Inner Write-Through cacheable, Outer Write-Through cacheable

3.3.2在AArch32状态下,可缓存性控制字段及其效果如下

translation regime Non-secure/secure 寄存器 说明
PL1&0 Non-secure SCTLR.C == 0 (1) 访问的内存数据在stage1转换都是 Non-cacheable
(2) 对stage1转换表的访问是 Non-cacheable
PL1&0 Non-secure SCTLR.I == 0 (1) 访问内存时的指令在所有stage1转换都是 Non-cacheable
PL1&0 Non-secure HCR2.CD == 1 (1) 访问的内存数据在stage2转换都是 Non-cacheable
(2) 对stage2转换表的访问是 Non-cacheable
PL1&0 Non-secure HCR2.ID == 1 (1) 访问内存时的指令在stage2转换都是 Non-cacheable
PL1&0 Non-secure HCR.DC == 1 (1) 所有stage1阶段转换和对 EL1&0 stage1转换表的所有访问都被视为对Non-shareable Inner Write-Back Cacheable Read-Allocate Write-Allocate, Outer Write-Back Cacheable Read-Allocate Write-Allocate的内存进行访问,无论SCTLR.C的值如何,这适用于数据和指令访问的转换
PL1&0 Non-secure SCTLR.M == 0 禁用了stage1 的translations ,则如果EL2使用AArch32并且HCR.DC的值为0,或者如果EL2使用AArch64并且HCR_EL2.DC的值为0,则:
(1) 如果SCTLR.I的值为0,从stage1访问内存的指令是 Outer Shareable, Inner Non-cacheable, Outer Non-cacheable;
(2) 如果SCTLR.I的值为1,从stage1访问内存的指令是 Outer Shareable, Inner Write-Through cacheable, Outer Write-Through cacheable;
PL1&0 secure SCTLR.C == 0 (1) 访问的内存数据在stage1转换都是 Non-cacheable
(2) 对stage1转换表的访问是 Non-cacheable
PL1&0 secure SCTLR.I == 0 (1) 访问内存时的指令都是 Non-cacheable
PL1&0 secure SCTLR.M == 0 禁用了stage1 的translations ,则如果EL2使用AArch32并且HCR.DC的值为0,或者如果EL2使用AArch64并且HCR_EL2.DC的值为0,则:
(1) 如果SCTLR.I的值为0,从stage1访问内存的指令是 Outer Shareable, Inner Non-cacheable, Outer Non-cacheable
(2) 如果SCTLR.I的值为1,从stage1访问内存的指令是 Outer Shareable, Inner Write-Through cacheable, Outer Write-Through cacheable
EL2 - HSCTLR.C == 0 (1) 对内存的数据访问都是 Non-cacheable
(2) 对EL2转换表的访问是 Non-cacheable
EL2 - HSCTLR.I == 0 (1) 访问内存时的指令都是 Non-cacheable
EL2 - HSCTLR.M == 0 禁用了stage1 的translations ,则如果EL2使用AArch32并且HCR.DC的值为0,或者如果EL2使用AArch64并且HCR_EL2.DC的值为0,则:
(1) 如果 HSCTLR.I 的值为0,从stage1访问内存的指令是 Outer Shareable, Inner Non-cacheable, Outer Non-cacheable
(2) 如果 HSCTLR.I 的值为1,从stage1访问内存的指令是 Outer Shareable, Inner Write-Through cacheable, Outer Write-Through cacheable

3.4 cache maintenance

1. Cache maintenance 指令对特定的内存位置起作用,指令作用的范围如下:

  • 某个虚拟地址,称为VA操作。
  • 特定的高速缓存行或者组和路,称为 set/way操作。

2. 按set/way操作Cache maintenance 指令的术语

术语 解释
Level 层次结构中的缓存级别,在Arm架构中,越低的缓存级别越靠近PE,armv8目前支持(Level 1 ~ Level 7)
set(组) 缓存的每一层都被分割成若干组。每一组是缓存层中的一组位置,可以为其分配一个地址。 在Arm架构中,组从0开始编号
way(路) 将cache平均分成多层,每一层称为一路。 在Arm架构中,路从0开始编号

3. Cache的管理的操作指令术语

术语 解释
Clean 整个高速缓存或者某个高速缓存行。相应的高速缓存行会被标记为脏,数据会写回到下一级高速缓存中或者主存储器中。
Invalidate 整个高速缓存或者某个高速缓存行。高速缓存上的数据会被丢弃
Clean and Invalidate 与执行clean指令后紧接着执行invalidate指令的行为相同。这两条指令在同一个位置执行
清零(Zero)操作 在某些情况下,对高速缓存进行清零操作起到一个预取和加速的功效,比如当程序需要使用一大块临时内存,在初始化阶段对这个内存进行清零操作,这时高速缓存控制器会主动把这些零数据写入高速缓存行中。若程序主动使用高速缓存的清零操作,那么将大大减少系统内部总线的带宽。

4. PoU和PoC
参见:Cache的相关知识(一) -10. PoU和PoC的区别

5. A64/A32 Cache maintenance instructions
(1) A64 Cache maintenance instructions

(2) AArch32 cache and branch predictor maintenance instructions

参考:

(1) 《Arm® Architecture Reference Manual Armv8, for Armv8-A architecture profile - The AArch64 System Level Memory Model D4.4 Cache support》。

有关AArch32/AArch64系统级内存模型(三)的更多相关文章

  1. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  2. ruby-on-rails - Rails - 子类化模型的设计模式是什么? - 2

    我有一个模型:classItem项目有一个属性“商店”基于存储的值,我希望Item对象对特定方法具有不同的行为。Rails中是否有针对此的通用设计模式?如果方法中没有大的if-else语句,这是如何干净利落地完成的? 最佳答案 通常通过Single-TableInheritance. 关于ruby-on-rails-Rails-子类化模型的设计模式是什么?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.co

  3. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

  4. ruby - 什么是填充的 Base64 编码字符串以及如何在 ruby​​ 中生成它们? - 2

    我正在使用的第三方API的文档状态:"[O]urAPIonlyacceptspaddedBase64encodedstrings."什么是“填充的Base64编码字符串”以及如何在Ruby中生成它们。下面的代码是我第一次尝试创建转换为Base64的JSON格式数据。xa=Base64.encode64(a.to_json) 最佳答案 他们说的padding其实就是Base64本身的一部分。它是末尾的“=”和“==”。Base64将3个字节的数据包编码为4个编码字符。所以如果你的输入数据有长度n和n%3=1=>"=="末尾用于填充n%

  5. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  6. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  7. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  8. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  9. ruby-on-rails - 如何将验证与模型分开 - 2

    我有一些非常大的模型,我必须将它们迁移到最新版本的Rails。这些模型有相当多的验证(User有大约50个验证)。是否可以将所有这些验证移动到另一个文件中?说app/models/validations/user_validations.rb。如果可以,有人可以提供示例吗? 最佳答案 您可以为此使用关注点:#app/models/validations/user_validations.rbrequire'active_support/concern'moduleUserValidationsextendActiveSupport:

  10. ruby-on-rails - Rails 模型——非持久类成员或属性? - 2

    对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs

随机推荐