armv8(aarch64)linux内核中flush_dcache_all函数详细分析【转】
转自:http://blog.csdn.net/qianlong4526888/article/details/12062809
版权声明:本文为博主原创文章,未经博主允许不得转载。
/*
* __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)
如果你对此有疑问,欢迎留言讨论。
armv8(aarch64)linux内核中flush_dcache_all函数详细分析【转】的更多相关文章
- armv8(aarch64)linux内核中flush_dcache_all函数详细分析
/* * __flush_dcache_all() * Flush the wholeD-cache. * Corrupted registers: x0-x7, x9-x11 */ ENTRY( ...
- Linux内核OOM机制的详细分析(转)
Linux 内核 有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了 防止内存耗尽而内核会把该进程杀掉.典 ...
- Linux内核中SPI总线驱动分析
本文主要有两个大的模块:一个是SPI总线驱动的分析 (研究了具体实现的过程): 另一个是SPI总线驱动的编写(不用研究具体的实现过程). 1 SPI概述 SPI是英语Serial Peripheral ...
- Linux内核中kzalloc函数详解
**************************************************************************************************** ...
- Linux内核OOM机制的详细分析【转】
本文转载自:http://blog.csdn.net/liukuan73/article/details/43238623 Linux内核根据应用程序的要求分配内存,通常来说应用程序分配了内存但是并没 ...
- Linux内核TCP MSS机制详细分析
前言 上周Linux内核修复了4个CVE漏洞[1],其中的CVE-2019-11477感觉是一个很厉害的Dos漏洞,不过因为有其他事打断,所以进展的速度比较慢,这期间网上已经有相关的分析文章了.[2] ...
- Linux内核中的Workqueue机制分析
1. 什么是workqueue Linux中的workqueue(工作队列)主要是为了简化在内核创建线程而设计的.通过相应的工作队列接口,可以使开发人员只关心与特定功能相关的处理流程,而不必关心内核线 ...
- Linux内核OOM机制的详细分析
Linux 内核有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了防止内存耗尽而内核会把该进程杀掉.典型的 ...
- Linux内核中container_of函数详解
http://www.linuxidc.com/Linux/2016-08/134481.htm
随机推荐
- iOS:后台定位并实时向服务器发送位置
第一步:开启后台模式,选中定位,选择project --> capabilities-->Backgorund Modes --> Location updates 如图: 第二步: ...
- python中反射(__import__和getattr使用)
反射: 1.可通过字符串的形式导入模块 1.1.单层导入 __import__('模块名') 1.2.多层导入 __import__(' list.text.commons',fromlist=Tru ...
- javascript设计模式学习之五——策略模式
一.策略模式定义: 定义一些列的算法/规则,将它们封装起来,使得它们可以互相替换/组合使用.其目的在于将算法/规则封装起来,将算法/规则的使用与实现分离出来. 通过策略模式,可以减少算法计算过程中大量 ...
- 遍历nsarray
// // main.m // 04-遍历数组 // // Created by apple on 14-3-21. // Copyright (c) 2014年 apple. All rig ...
- 使用IXmlSerializable的问题
最近又开始使用XML了,但今天遇到一个折腾我一下午加一个晚上的时间,终于从网络上找到相关的资料解决了. 有一个成员是用来存放正则表达式的,由于里面包含其它字符,所以想用CDATA来保存方便查看,所以想 ...
- Java基础之在窗口中绘图——使用模型/视图体系结构在视图中绘图(Sketcher 1 drawing a 3D rectangle)
控制台程序. 在模型中表示数据视图的类用来显示草图并处理用户的交互操作,所以这种类把显示方法和草图控制器合并在一起.不专用于某个视图的通用GUI创建和操作在SketcherFrame类中处理. 模型对 ...
- Git_Commands
- iOS中model出来一个控制器的尺寸怎么设置?
在xib的控制器里添加self.preferredContentSize = CGSizeMake( , ) 就能修改xib在界面上显示的大小- (void)viewDidLoad { [super ...
- Climbing Stairs - Print Path
stair climbing, print out all of possible solutions of the methods to climb a stars, you are allowed ...
- vs2015社区版不支持installshield
开始学习vs了 下一步就是在这个平台上提升技术咯. 写了老师上课讲的算法 生成了个VB程序结果不能在别的电脑上运行 .幸好我自己测试了下.要是直接拿去学校不是很~ 然后我就想到当初接触易语言时候的搞静 ...