首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >arm Linux_arch linux

arm Linux_arch linux

作者头像
全栈程序员站长
发布2022-11-10 17:22:56
发布2022-11-10 17:22:56
18.5K0
举报

/*

* __flush_dcache_all()

* Flush the wholeD-cache.

* Corrupted registers: x0-x7, x9-x11

*/

ENTRY(__flush_dcache_all)

//保证之前的访存指令的顺序

dsb sy

//读cache level id register

mrs x0, clidr_el1 // read clidr

//取bits[26:24](Level of Coherency for the cache hierarchy.)

//需要遵循cache一致性的cache层级(例如有3级cache,但2级需要做一致性)

and x3, x0, #0x7000000 // extract loc from clidr

//逻辑右移23位,把bits[26:24]放到bits[2:0]

lsr x3, x3, #23 // left align loc bit field

//如果需要做cache一致性的层级为0,则不需要flush,跳转到finished标记处。

cbz x3, finished // if loc is 0, then no need toclean

//x10存放cache级,从level0 cache开始做flush

//以下三个循环loop3是set/way(x9),

//loop2是index(x7),loop1是cache level(x10)

mov x10, #0 // start clean at cache level 0

loop1:

//x10+2后右移一位正好等于1,再加上x10本身正好等于3

//每执行一次loop1,x2+3*执行次数,目的在于把x0(clidr_el1)右移3位,

//取下一个cache的ctype type fields字段,clidr_el1的格式见《ARMv8 ARM》

add x2, x10, x10, lsr #1 /

//x0逻辑右移x2位,给x1,提取cache类型放到x1中,x0中存放:clidr_el1

lsr x1, x0, x2

//掩掉高位,只取当前cache类型

and x1, x1, #7

/* 判断当前cache是什么类型:

* 000 No cache.

* 001 Instruction cache only.

* 010 Data cache only.

* 011 Separate instruction and data caches.

* 100 Unified cache.

*/

//小于2说明data cache不存在或者只有icache,

//跳转skip执行,大于等于2继续执行

cmp x1, #2

b.lt skip

/*

* Save/disableand restore interrupts.

* .macro save_and_disable_irqs, olddaif

* mrs \olddaif,daif

* disable_irq

* .endm

*/

//保存daif到x9寄存器中,关闭中断

save_and_disable_irqs x9 // make CSSELR and CCSIDR access atomic

//选择当前cache级进行操作,csselr_el1寄存器bit[3:1]选择要操作的cache级

//第一次执行时x10=0,选择level 0级cache

msr csselr_el1,x10

//isb用于同步新的cssr和csidr寄存器

isb

//因为执行了“msr csselr_el1,x10”,所以要重新读取ccsidr_el1

mrs x1, ccsidr_el1 // read the new ccsidr

/*

* .macro restore_irqs, olddaif

* msrdaif, \olddaif

. * endm

*/

restore_irqs x9

//x1存储ccsidr_el1内容,低三位是(Log2(Number of bytes in cache line)) – 4

//加4后x2=(Log2(Numberof bytes in cache line))

and x2, x1, #7 // extract the length of the cachelines

add x2, x2, #4 // add 4 (line length offset)

mov x4, #0x3ff

//逻辑右移3位,提取bits[12:3](Associativityof cache) – 1,

//x4存储cache的way数

and x4, x4, x1, lsr #3 // find maximum number on the way size

//计算x4前面0的个数,存到x5

clz x5, x4 // find bit position of way sizeincrement

//提取bits[27:13]位:(Number of sets in cache) – 1

mov x7, #0x7fff

//x7中存储cache中的set数

and x7, x7, x1, lsr #13 // extract max number of the index size

loop2:

//把x4值备份

mov x9, x4 // create working copy of max waysize

loop3:

//把需要操作哪个way存储到x6

lsl x6, x9, x5

//确定操作哪一级的哪个way(x10指定操作哪一级cache)

orr x11, x10, x6 // factor way and cache number intox11

//确定操作哪个set

lsl x6, x7, x2

orr x11, x11, x6 // factor index number into x11

//x11中存储了哪一级cache(10),哪一路cache(x9),哪个set(x7)

dc cisw, x11 // clean & invalidate by set/way

//way数-1

subs x9, x9, #1 // decrementthe way

b.ge loop3

subs x7, x7, #1 // decrementthe index

b.ge loop2

skip:

add x10, x10, #2 // increment cache number,

//为什么加2不是1?见loop1标号处解释

cmp x3, x10

b.gt loop1

finished:

mov x10, #0 // swith back to cache level 0

msr csselr_el1, x10 // select current cache level incsselr

dsb sy

isb

ret

ENDPROC(__flush_dcache_all)

如果你对此有疑问,欢迎留言讨论。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/184707.html原文链接:https://javaforall.cn

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022年10月8日 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档