1.1

/*

*  __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是cachelevel(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/disable and 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

* msr daif, \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

clzx5, 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 Linux内核源代码分析:__flush_dcache_all()的更多相关文章

  1. Linux内核源代码分析方法

    Linux内核源代码分析方法   一.内核源代码之我见 Linux内核代码的庞大令不少人"望而生畏",也正由于如此,使得人们对Linux的了解仅处于泛泛的层次.假设想透析Linux ...

  2. Linux 内核源代码分析 chap 2 存储管理 (5)

    物理页面分配 linux 内核 2.4 中有 2 个版本号的物理页面分配函数 alloc_pages(). 一个在 mm/numa.c 中, 还有一个在 mm/page_alloc.c 中, 依据条件 ...

  3. linux 内核源代码分析 - 获取数组的大小

    #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 測试程序: #include<stdio.h> #include<stdlib. ...

  4. ARMv8 Linux内核异常处理过程分析

    NOTE:为了方便大家阅读,制作了PDF版文档.下载请猛戳这里 老样子,为了赚点积分下载其它人的文件,下载以上资料须要资源分2分. 假设没有积分请留言全部文档,留下邮箱就可以. 看了Linaro提供的 ...

  5. Linux内核源代码情景分析系列

    http://blog.sina.com.cn/s/blog_6b94d5680101vfqv.html Linux内核源代码情景分析---第五章 文件系统  5.1 概述 构成一个操作系统最重要的就 ...

  6. 《深入分析Linux内核源代码》读书、私藏笔记大放送

    秉承着"不懂操作系统原理的程序员不是合格的程序员"的至理名言,鄙人又是买陈莉君老师的“Linux教学视频”,又是研读其力作<深入分析Linux内核源代码>,先将总结笔记 ...

  7. 《LINUX3.0内核源代码分析》第二章:中断和异常 【转】

    转自:http://blog.chinaunix.net/uid-25845340-id-2982887.html 摘要:第二章主要讲述linux如何处理ARM cortex A9多核处理器的中断.异 ...

  8. Linux pipe 源代码分析

    Linux pipe 源代码分析      管道pipe作为Unix中历史最悠久的IPC机制,存在各个版本号的Unix中,主要用于父子进程之间的通信(使用fork,从而子进程会获得父进程的打开文件表) ...

  9. Linux内核源代码获取教程

    Linux内核源代码获取方法 什么叫Linux 什么叫Linux内核 Linux内核源代码的获取 什么叫Linux? Linux是一套免费使用和自由传播的类Unix操作系统,是一个基于POSIX和UN ...

随机推荐

  1. HTML5 总结-表单-输入类型

    HTML5 Input 类型 HTML5 新的 Input 类型 HTML5 拥有多个新的表单输入类型.这些新特性提供了更好的输入控制和验证. 本章全面介绍这些新的输入类型: email url nu ...

  2. seajs + easyui [转]

    * *content seajs+easyui使用 */ /** * 首先来看看在seajs中jquery和jquery插件如何使用 */ 1.jquery.js define(function(re ...

  3. python2.7_1.3_获取远程设备的IP地址

    代码如下: # -*- coding: utf-8 -*- import socket def get_remote_machine_info(): remote_host = 'www.python ...

  4. c++设计模式总结 好久没写博客了 实在是忙

    具体代码就不贴出来了   通俗易懂的理解方式      原创 c++设计模式: 简单工厂模式 工厂模式有一种非常形象的描述,建立对象的类就如一个工厂,而需要被建立的对象就是一个个产品:在工厂中加工产品 ...

  5. 64位CentOS上编译 Hadoop 2.2.0

    下载了Hadoop预编译好的二进制包,hadoop-2.2.0.tar.gz,启动起来后.总是出现这样的警告: WARN util.NativeCodeLoader: Unable to load n ...

  6. 【Hibernate】HQL new map

    HQL 查询如果需要带出对象(比如:OneToOne子对象)的一两个属性,而不是全部带出.可以使用 select new map的方法带出. 1.lazy还是设置为false /**关联属性对象*/ ...

  7. unity学习中经常要碰到的几种数据结构

    常碰到的几种数据结构:1.Array,2.ArrayList,3.List<T>,4.LinkedList<T>,5.Queue<T>,6.Stack<T&g ...

  8. Tomcat免安装版的环境变量配置以及Eclipse下的Tomcat配置和测试

    Tomcat是目前比较流行的开源且免费的Web应用服务器,在我的电脑上第一次安装Tomcat,再经过网上教程和自己的摸索后,将这个过程 重新记录下来,以便以后如果忘记了可以随时查看. 注意:首先要明确 ...

  9. [Swust OJ 191]--迷宫逃离(打表搜索)

      题目链接:http://acm.swust.edu.cn/problem/191/ Time limit(ms): 1000 Memory limit(kb): 65535   江鸟突然想到了一个 ...

  10. POJ2728 最小比率生成树/0-1分数规划/二分/迭代(迭代不会)

    用01分数规划 + prime + 二分 竟然2950MS惊险的过了QAQ 前提是在TLE了好几次下过的 = = 题目意思:有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水,只要两个村庄之间有一 ...