转自: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函数详细分析【转】的更多相关文章

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

    /* *  __flush_dcache_all() *  Flush the wholeD-cache. * Corrupted registers: x0-x7, x9-x11 */ ENTRY( ...

  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. iOS:如何将自己的SDK用CocoaPods管理

    条件:  需要在终端上将工程发布到cocoapods上,这样才能用cocoapods进行管理. 步骤: 首先,你得有一个pod的账号 在终端中输入pod 可以查看关于pod 的命令帮助,输入pod t ...

  2. 微信支付开发(1) 微信支付URL配置

    由于微信支付接口更新,本文档已过期,请查看新版微信支付教程.地址 http://www.cnblogs.com/txw1958/category/624506.html 本文介绍微信支付申请时如何设置 ...

  3. 【关于HBITMAP, DC, MEM DC, Clipboard】将HBITMAP拷贝到Clipboard(Windows Clipboard & OLE Clipboard)

    参考: Programming Windows with MFC, 2nd. Chapter 18, 19. 建议把这两章学习完(至少到OLE drag-and-drop之前要学习完)再来尝试OLE ...

  4. maven 无法安装plugin的问题

    spring有一个入门例子,在docker里跑spring-boot程序 下载后按照教程执行mvn package docker:build.并不能成功.会报错. [ERROR] No plugin ...

  5. git提交

    1.git pull 本地已经commit 2.git checkout master 3.git pull 4.git checkout - 5.git merge master 6.git pus ...

  6. linux下gcc默认搜索头文件及库文件的路径

    一.头文件gcc 在编译时如何去寻找所需要的头文件:※所以header file的搜寻会从-I开始※然后找gcc的环境变量 C_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJC ...

  7. SQL 数据库备、还,附、分,数据查询,聚合函数

    认识数据库备份和事务日志备份 数据库备份与日志备份是数据库维护的日常工作,备份的目的是在于当数据库出现故障或者遭到破坏时可以根据备份的数据库及事务日志文件还原到最近的时间点将损失降到最低点. 数据库备 ...

  8. spring 官方下载地址

    SPRING官方网站改版后,建议都是通过Maven和Gradle下载,对不使用Maven和Gradle开发项目的,下载就非常麻烦. 下给出Spring Framework jar官方直接下载路径: h ...

  9. 资源Createwindow,对应标识符,绑定窗口

    问? 定义一个CEdit cedit1:怎么和IDC_EDIT1 关联,可以在CEdit.Create()里传进去或者在DoDataExchange()里面绑定,是不是一定要先弄出个IDC_EDIT1 ...

  10. Python之urllib2

    urllib2 - extensible library for opening URLs Note The urllib2 module has been split across several ...