转自: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. ssh secure shell client

    登陆方式和putty一样

  2. VMWare虚拟机下为Ubuntu 12.04.1配置静态IP_转

    转自:http://www.cnblogs.com/objectorl/archive/2012/09/27/vmware-ubuntu-nat-static-ip-settings.html 背景在 ...

  3. CString + UINT Error:有多个运算符"+="与这些操作数匹配

    在OnChar中,参数UINT nChar 有一个CString str,现在执行 str += nChar报错:Error:有多个运算符"+="与这些操作数匹配 解决办法:把UI ...

  4. iOS的三种多线程技术NSThread/NSOperation/GCD

    1.iOS的三种多线程技术 1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 2.以下两点是苹果专门开发的"并发"技术,使得程序员可以不再去关心 ...

  5. mysql及redis环境部署时遇到的问题解决

    redis开启远程访问redis默认只允许本地访问,要使redis可以远程访问可以修改redis.conf打开redis.conf文件在NETWORK部分有说明 解决办法:注释掉bind 127.0. ...

  6. yum只下载安装需要的rpm包

    1.安装yum的插件yum-downloadonly yum -y install yum-downloadonly 2.使用 yum -y install somepackges --downloa ...

  7. The prefix "mx" for element "mx:WindowedApplication" is not bound.

    <mx:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"  > ......出现了错误The p ...

  8. (Abstract Factory)抽象工厂

    定义: 抽象工厂同工厂方法有相似处:都提供了对子类创建的封装,都是有工厂方法的接口实现类的中决定了子类被创建为什么对象. 不同于工厂方法之处:工厂方法创建的对象只是一个类型的子类,而抽象工厂创建的对象 ...

  9. Three.js基础探寻九——网格

    在学习了几何形状和材质之后,我们就能使用他们来创建物体了.最常用的一种物体就是网格(Mesh),网格是由顶点.边.面等组成的物体:其他物体包括线段(Line).骨骼(Bone).粒子系统(Partic ...

  10. replication_slot and PostgreSQL Replication

    主库IP:192.168.230.128 备库IP:192.168.230.129 PostgreSQL版本: 主备机PostgreSQL源码包均位于/opt/soft_bak OS:CentOS5 ...