/*

*  __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

后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函数详细分析的更多相关文章

  1. armv8(aarch64)linux内核中flush_dcache_all函数详细分析【转】

    转自:http://blog.csdn.net/qianlong4526888/article/details/12062809 版权声明:本文为博主原创文章,未经博主允许不得转载. /* *  __ ...

  2. Linux内核OOM机制的详细分析(转)

    Linux 内核 有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了 防止内存耗尽而内核会把该进程杀掉.典 ...

  3. Linux内核中SPI总线驱动分析

    本文主要有两个大的模块:一个是SPI总线驱动的分析 (研究了具体实现的过程): 另一个是SPI总线驱动的编写(不用研究具体的实现过程). 1 SPI概述 SPI是英语Serial Peripheral ...

  4. Linux内核中kzalloc函数详解

    **************************************************************************************************** ...

  5. Linux内核OOM机制的详细分析【转】

    本文转载自:http://blog.csdn.net/liukuan73/article/details/43238623 Linux内核根据应用程序的要求分配内存,通常来说应用程序分配了内存但是并没 ...

  6. Linux内核TCP MSS机制详细分析

    前言 上周Linux内核修复了4个CVE漏洞[1],其中的CVE-2019-11477感觉是一个很厉害的Dos漏洞,不过因为有其他事打断,所以进展的速度比较慢,这期间网上已经有相关的分析文章了.[2] ...

  7. Linux内核中的Workqueue机制分析

    1. 什么是workqueue Linux中的workqueue(工作队列)主要是为了简化在内核创建线程而设计的.通过相应的工作队列接口,可以使开发人员只关心与特定功能相关的处理流程,而不必关心内核线 ...

  8. Linux内核OOM机制的详细分析

    Linux 内核有个机制叫OOM killer(Out-Of-Memory killer),该机制会监控那些占用内存过大,尤其是瞬间很快消耗大量内存的进程,为了防止内存耗尽而内核会把该进程杀掉.典型的 ...

  9. Linux内核中container_of函数详解

    http://www.linuxidc.com/Linux/2016-08/134481.htm

随机推荐

  1. makeKeyAndVisible的作用

    [self.window makeKeyAndVisible]; 这个是便捷方法,去使被使用对象的主窗口显示到屏幕的最前端.你也可以使用hiddenUIView方法隐藏这个窗口

  2. OpenStack Cinder源代码流程简析

    版权声明:本博客欢迎转载,转载时请以超链接形式标明文章原始出处!谢谢! 博客地址:http://blog.csdn.net/i_chips 一.概况 OpenStack的各个模块都有对应的client ...

  3. Linux 监控CPU 温度

      安装测试系统: 硬件:普通PC机, 软件:redhat linux as 4  2.6 .9 , 安装系统自带的lm_sensors-2.8.7-2.i386 你也可以从[url]http://w ...

  4. cocos2d疑问

    1. pushScene后,如果才能保持前一个Scene的所有动作,比如schedule 2. APP进入到背景模式运行时,如何让它仍然做一些工作?

  5. Android(java)学习笔记235:多媒体之计算机图形表示方式

    1.多媒体 很多媒体:文字(TextView,简单不讲),图片,声音,视频等等.   2.图片 计算机如何表示图片的? (1)bmp 高质量保存    256色位图:图片中的每个像素点可以有256种颜 ...

  6. codevs 1997 守卫者的挑战

    /* 表示很遗憾.. 开始状态想的没错 就是转移的时候出了问题 自己也想到了数组平移 然而没往下写 与正解擦肩而过…. 然后为了好转移写了个4维的 时间不多了没来得及降维 草草的算算空间就交了… 尼玛 ...

  7. MD5算法的使用

    using System.Security.Cryptography; using System.Text; StringBuilder sb = new StringBuilder();//构建一个 ...

  8. iOS开发中EXC_BAD_ACCESS的另类原因

    今天偶然学习iOS开发的时候碰到一个EXC_BAD_ACCESS的异常,经查资料得到的解释是由于访问了已经被回收了堆内存对象导致的,参考: http://code.tutsplus.com/tutor ...

  9. AFN发送请求失败

    发送请求出现这个错误 Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Coc ...

  10. JavaScript--循环--打印星星和99乘法表

    1.打印99乘法表 function chengfa(){ //反复调用公式 for(var r=1;r<=9;r++){ for(var i=1,str="";i<= ...