ARMv8如何读取cache line中MESI 状态以及Tag信息(tag RAM & dirty RAM)并以Cortex-A55示例

这篇具有很好参考价值的文章主要介绍了ARMv8如何读取cache line中MESI 状态以及Tag信息(tag RAM & dirty RAM)并以Cortex-A55示例。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一,系统寄存器以及读写指令

本文以Cortex-A55处理器为例,通过访问 处理器中的内部存储单元(tag RAM和dirty RAM),来读取cache line 中的MESI信息。
Cortex-A55提供了一种通过读取一些系统寄存器,来访问Cache 和 TLB使用的一些内部存储单元(internal memory)的机制。这个功能可以探查出当缓存中的数据与主存中的数据不一致时存在的问题。
此外,AArch64模式和AArch32模式的读取方式不同:
当处理器处于AArch64模式时,先通过一些只写(write-only)寄存器来选择具体的cache line和内存地址,然后通过只读寄存器来读取具体的tag信息。下图为相关寄存器以及相关操作指令,需要注意的是,这些操作只在EL3时可用,如果在其他模式下使用这些指令,将会进入Undefined Instruction 异常。
ARMv8下,AArch64的EL3如下图红框所示:
ARMv8如何读取cache line中MESI 状态以及Tag信息(tag RAM & dirty RAM)并以Cortex-A55示例,ARM,ARM Cache,cache,MESI,tag ram,dirty ram,internal memory,ARM,Cortex-A55
AArch64下获取内部存储单元信息的相关寄存器以及指令:
ARMv8如何读取cache line中MESI 状态以及Tag信息(tag RAM & dirty RAM)并以Cortex-A55示例,ARM,ARM Cache,cache,MESI,tag ram,dirty ram,internal memory,ARM,Cortex-A55

当处理器处于AArch32模式下时,先通过一些只写(write-only)CP15寄存器来选择具体的cache line和内存地址,然后通过只读CP15寄存器来读取具体的tag信息。下图为相关寄存器以及相关操作指令,需要注意的是,这些操作只在EL3时可用,如果在其他模式下使用这些CP15指令,将会进入Undefined Instruction 异常。
ARMv8下,AArch32的EL3如下图红框所示:
ARMv8如何读取cache line中MESI 状态以及Tag信息(tag RAM & dirty RAM)并以Cortex-A55示例,ARM,ARM Cache,cache,MESI,tag ram,dirty ram,internal memory,ARM,Cortex-A55
AArch32下获取内部存储单元信息的相关寄存器以及指令:
ARMv8如何读取cache line中MESI 状态以及Tag信息(tag RAM & dirty RAM)并以Cortex-A55示例,ARM,ARM Cache,cache,MESI,tag ram,dirty ram,internal memory,ARM,Cortex-A55
Cortex-A55支持一下内部存储单元信息的获取:

  • L1 data cache
  • L1 instruction cache
  • L2 TLB
  • Main TLB RAM
  • Walk cache
  • IPA cache

二,Cortex-A55 Data cache的MESI信息获取(AARCH 64)

接下来,本文以Cortex-A55的Data cache为例,读取其某个cache line的tag信息,其具体的步骤很简单,分为两步:

  1. 写入Data Cache Tag Read Operation Register,写入的内容为具体的Set和way信息,通过way index和set index来定位到想要读取的cache line。
  2. 读取相应的 Data Register 0 和 Data Register 1寄存器,通过对Data Register寄存器里面的数据进行解码,来获取tag 信息。

2.1 将Set/way信息写入Data Cache Tag Read Operation Register

首先,我们需要从一个虚拟地址(VA)中解析出Set index信息。
下图为Cortex-A57的4-way组相连的32KB大小的data cache结构,其cache line大小也为64 bytes,从图中可知,一个VA可以被分成几个部分:Tag,Set index,word index以及byte index。其中Set index = VA[13:6]。
ARMv8如何读取cache line中MESI 状态以及Tag信息(tag RAM & dirty RAM)并以Cortex-A55示例,ARM,ARM Cache,cache,MESI,tag ram,dirty ram,internal memory,ARM,Cortex-A55
在另一个实例中,32KB大小的4-way组相连data cache,cache line大小为32 bytes,其Set index = VA[12:5]:
ARMv8如何读取cache line中MESI 状态以及Tag信息(tag RAM & dirty RAM)并以Cortex-A55示例,ARM,ARM Cache,cache,MESI,tag ram,dirty ram,internal memory,ARM,Cortex-A55
Cortex-A55的Data cache为4-way 组相连结构。假设其为32KB,一个cache line的大小为64 bytes,我们就可以求出该data cache中有 32 KB / 64 B / 4 = 2^7 = 128个set(组),也就是说至少需要7个bit才能完整解析出具体的set index。如下图所示,可以通过公式:

S = log2(Data cache size / 4).
S=12 For a 16KB cache.
S=13 For a 32KB cache.
S=14 For a 64KB cache.

来计算出Set index的范围:Set index = VA[12:6]。
由于是4-way 组相连结构,cache line 可以存在与任意一个way中,所以我们的cache way可能为0,1,2,3中任意一个数字。
求得了set和way的index后,需要对其进行编码,然后写入到Data Cache Tag Read Operation Register寄存器中。其编码规则如下图所示,只需将Set和way的值写入对应的bit中即可,其中Rd[5:3]为cahche double word数据的偏移量,由于本次示例是读取tag信息,所以Rd[5:3]为0即可。
ARMv8如何读取cache line中MESI 状态以及Tag信息(tag RAM & dirty RAM)并以Cortex-A55示例,ARM,ARM Cache,cache,MESI,tag ram,dirty ram,internal memory,ARM,Cortex-A55

所以我们要写入Data Cache Tag Read Operation Register的Rd的值可以通过以下代码获取:

unsigned int get_Rd_data(int * VA, way_num)
{
	unsigned int set_way_index = VA | 0x1FC0; //get way index, VA[12:6]
	set_way_index |= way_num < 30; //way_num could be 0,1,2,3 
	return set_way_index;
}

Rd中除了Set和way信息,其他值均为0,0x1FC0为VA[12:6]全为1的情况:
ARMv8如何读取cache line中MESI 状态以及Tag信息(tag RAM & dirty RAM)并以Cortex-A55示例,ARM,ARM Cache,cache,MESI,tag ram,dirty ram,internal memory,ARM,Cortex-A55
然后我们使用如下指令将Rd的值写入,假设Rd为R0:

MSR S1_6_c15_c2_0, x0; x0 = get_Rd_data(VA,way_num)

2.2 读取Data Register 1和Data Register 0数据并解码

将Set/way信息写入Data Cache Tag Read Operation Register 后,相当于选择了想要操作的cache line,接下来我们将读取Data Register 1和Data Register 0的数据来获取该cache line里的tag信息,除了tag信息外,我们还可以从Data Register 1和Data Register 0两个寄存器中获取:

  1. MESI 状态信息
  2. outer内存属性
  3. valid 信息

可获得的信息具体见下图:
ARMv8如何读取cache line中MESI 状态以及Tag信息(tag RAM & dirty RAM)并以Cortex-A55示例,ARM,ARM Cache,cache,MESI,tag ram,dirty ram,internal memory,ARM,Cortex-A55

需要注意的是,如果是想获取MESI状态信息,则需要两个寄存器配合使用,即读取Data Register 0 [4] - Dirty以及Data Register 1 [31:30] - MESI
Data Register 0 [4]里的为来自Dirty RAM的Dirty bit,用于判断当前cache line 是否为diry。

  • 0:clean
  • 1:dirty

Data Register 1 [30:29]里的为来自tag RAM的MESI信息:

  • 0b00 Invalid
  • 0b01 Shared
  • 0b10 Unique non-transient
  • 0b11 Unique transient

关于transient的概念本文这里不做过多描述,读者可以自行查阅ARM相关文档:

In Armv8, it is IMPLEMENTATION DEFINED whether a Transient hint is supported. In an implementation that supports the Transient hint, the Transient hint is a qualifier of the cache allocation hints, and indicates that the benefit of caching is for a relatively short period. It indicates that it might be better to restrict allocation of transient entries, to avoid possibly casting-out other, less transient, entries.
A55 has a specific behavior for memory regions that are marked as Write-Back cacheable and transient, as defined in the Armv8 A architecture:

  • For any load that is targeted at a memory region that is marked as transient, the following occurs:
    • If the memory access misses in the L1 data cache, the returned cache line is allocated in the L1 data cache but is marked as transient.
    • On eviction, if the line is clean and marked as transient, it is not allocated into the L2 cache but is marked as invalid.
  • For stores that are targeted at a memory region that is marked as transient, if the store misses in the L1 data cache, the line is allocated into the L2 cache.

关于MESI信息,读者只需知道transient hint是一种由具体架构实现定义的一种属性,本文假设当前环境没有实现transient,所以Data Register 1 [30:29] MESI信息里的Unique表示为 0b10。
根据笔者的上篇博文:缓存一致性(cache coherency)解决方案:MESI 协议状态转换详解 可知,来自tag RAM的MESI信息需要和Dirty bit一起组合使用,才能表示出完整的MESI信息:

  • M,Modified, Unique Dirty((UD), 只存在于当前cache中(unique),并且该cache line上的数据与下一级存储单元中的数据不同(dirty)。换言之,cache line中最新的数据位于当前cache,其他cache中没有备份 ,cache line中的内容与主存中的不一致。
  • E,Exclusive, Unique Clean(UC),数据只存在于当前cache line中,并且为clean的。cache中cache line中的数据于主存中的一致,并且其他core中的cache没有该地址的数据备份,只存在一个cache中。
  • S,Shared Clean (SC), Shared ,cache line中的data不一定与主存中的一致,但是shared cache line中的数据是最新的,且存在于多个core中。
  • I,Invalid,无效的数据,或者可以说当前cache line里没有数据。

最后可以得出如下组合关系:
ARMv8如何读取cache line中MESI 状态以及Tag信息(tag RAM & dirty RAM)并以Cortex-A55示例,ARM,ARM Cache,cache,MESI,tag ram,dirty ram,internal memory,ARM,Cortex-A55

比如读取到的Data Register 0 [4]为1,以及Data Register 1 [31:30]为2,根据上图的组合关系,可知当前cache line的MESI状态为 Unique+Dirty = Modified

完整的获取MESI信息的示例代码如下:

; step 1: write set index and way num into Data Cache Tag Read Operation Register
MSR S1_6_c15_c2_0, x0; x0 = get_Rd_data(VA,way_num)
; step 2: read Data Register 1 and Data Register 0
MRS x1, S3_6_c15_c0_0   ;x1 =  Data Register 0 
MRS x2, S3_6_c15_c0_1    ;x2 =  Data Register 1 

参考文章:

cortex_a55_trm_100442_0200_01_en.pdf文章来源地址https://www.toymoban.com/news/detail-733571.html

到了这里,关于ARMv8如何读取cache line中MESI 状态以及Tag信息(tag RAM & dirty RAM)并以Cortex-A55示例的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Armv9读取cache内容:Direct access to internal memory

    快速链接: 【精选】ARMv8/ARMv9架构入门到精通-[目录] 👈👈👈 10 访问cache Cortex-A720核心提供一种机制,通过IMPLEMENTATION DEFINED系统寄存器可以读取L1缓存、L2缓存和Translation Lookaside Buffer(TLB)。当缓存数据与系统内存数据之间的一致性异常时,您可以使用此机制来调查任何问题

    2024年04月24日
    浏览(47)
  • 如何在armv6 armv7 armv8(aarch64)嵌入式板子上面安装nginx服务器,支持H265码流

    为什么要在板子瑞芯微rv1126核心板上面安装nginx服务器,是因为我的项目需要用到拉到连接在板子上面的摄像头,由于是摄像头是直连摄像头的只能通过板子上面的wifi热点设备,先连接这个热点才能获取到这个网络摄像头,那么就需要板子做一个推流的服务器让摄像头的画面

    2024年02月15日
    浏览(51)
  • 如何剪裁操作系统源码——移植FreeRTOS的内存管理模块到ARMV8裸片

    本文面向的需求场景是,为缺乏标准库实现的处理器IP移植内存管理模块,即为裸片部署C标准库中的 malloc() 和 free() 函数。 具体做法是——从操作系统的内存管理组件中剪裁出必要的源码,适配到目标处理器的开发环境(SDK/IDE/CMAKE工程子目录)中。 1.1 C标准库中的内存管理

    2024年02月13日
    浏览(40)
  • 【ARMv8 SIMD和浮点指令编程】NEON 存储指令——如何将数据从寄存器存储到内存?

    和加载指令一样,NEON 有一系列的存储指令。比如 ST1、ST2、ST3、ST4。 1 ST1 (multiple structures) 从一个、两个、三个或四个寄存器存储多个单元素结构。该指令将元素从一个、两个、三个或四个 SIMDFP 寄存器存储到内存,无需交错。每个寄存器的每个元素都被存储。 无偏移 一个寄

    2024年02月07日
    浏览(50)
  • 【ARMv8 SIMD和浮点指令编程】NEON 加载指令——如何将数据从内存搬到寄存器(其它指令)?

    除了基础的 LDx 指令,还有 LDP、LDR 这些指令,我们也需要关注。 1 LDNP (SIMDFP) 加载 SIMDFP 寄存器对,带有非临时提示。该指令从内存加载一对 SIMDFP 寄存器, 向内存系统发出访问是非临时的提示 。用于加载的地址是根据基址寄存器值和可选的立即偏移量计算得出的。 32-bit (

    2024年02月07日
    浏览(46)
  • 解决C#报“MSB3088 未能读取状态文件*.csprojAssemblyReference.cache“问题

        今天在使用vscode软件+C#插件,编译.cs文件时,发现如下warning: 图(1) C#报cache没有更新     出现该warning的原因: 当前.cs文件修改了,但是其缓存文件*.csprojAssemblyReference.cache没有更新,需要重新清理一下工程,再编译、运行即可。     命令如下:     或者手动在vs里

    2024年02月11日
    浏览(50)
  • 【ARMv8M Cortex-M33 系列 7.4 -- 如何使能 usagefault | memmange fault | bus fault 中断】

    请阅读 【嵌入式开发学习必备专栏 之 ARM Cortex-Mx专栏】 由于文章【ARMv8M Cortex-M33 系列 7.2 – HardFault 问题定位 1】 中提到了HardFault 的发生是由于其它异常所升级导致的,所以就需要调查下如何是能其它异常中断。 在 ARM Cortex-M33 核心上启用 UsageFault 、 MemManageFault 和 BusFault 异

    2024年01月20日
    浏览(51)
  • ARMv8 汇编指令

    MOV Xd|SP, Xn|SP MOV Xd|SP, #imm16 常用于寄存器之间的搬移和立即数搬移,   仅仅支持imm16, 0-4096大小范围的立即数操作 MRS: 状态寄存器 -- 通用寄存器的传送指令。 MSR: 通用寄存器 -- 状态寄存器的传送指令。 注意:在ARMv7里通过CP15协处理器方位系统寄存器 还可以访问PSTATE寄存器一

    2024年04月27日
    浏览(42)
  • ARMv8架构简介

    ARMv8‑A 架构是针对应用程序配置文件的最新一代 ARM 架构。 ARMv8 这个名称用于描述整体架构,现在包括 32 位执行状态和 64 位执行状态。它引入了使用 64 位宽寄存器执行的能力,同时保持与现有 ARMv7 软件的向后兼容性。 ARMv8‑A 架构引入了许多更改,可以设计出性能显着提高

    2024年02月04日
    浏览(44)
  • [笔记]ARMv7/ARMv8 交叉编译器下载

    开发 Cortex-A7、Cortex-A72 或其他 ARM 架构 profile 芯片时,经常需要下载对应架构的交叉编译器,所以写这篇笔记,用于记录一下交叉编译器下载流程,免得搞忘。 编译环境:ubuntu 虚拟机 下载地址 我们可以从 ARM 官网的 Arm Developer下载交叉编译器,这个网站也包含几乎所有的 A

    2024年02月02日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包