armv8(aarch64)linux核心中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
//
//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
//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函式詳細分析
/* * Flush the wholeD-cache. * Corrupted registers: x0-x7, x9-x11 */ ENTRY(__flush_dcache_all
linux核心中2410_gpio_cfgpin函式分析
2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPIO_OUTPUT) 函式分析:作用設定相應GPIO口的工作模式,輸入、輸出、中斷等。 一,首先巨集展開:為方便描述,展開後用等號表示 #define S3C2410_GPIO
Linux核心中trace_xxxx()函式的定義
Linux中trace_xxxx()函式的定義 以trace_netif_receive_skb(skb);為例 該函式的定義: 其中DEFINE_EVENT定義為(include/linux/
Linux核心中的bsearch二分查詢函式
/* * bsearch - binary search an array of elements * @key: pointer to item being searched for * @base
linux核心中GPIO的使用(二)--標準介面函式
在linux核心中,有一些基本模組可以使用標準的介面函式來操作,比如GPIO、interrupt、clock,所謂的標準介面函式是指一些與硬體平臺無關的、linux下做驅動通用的函式, 常用的有: gpio_request();gpio_free()
linux核心中:likely和unlikely函式
核心原始碼:linux-2.6.38.8.tar.bz2 在Linux核心中likely和unlikely函式有兩種(只能兩者選一)實現方式,它們的實現原理稍有不同,但作用是相同的,下面將結合linux-2.6.38.8版本的核心程式碼來進行講解。
linux核心中的copy_to_user和copy_from_user
Kernel version:2.6.14 CPU architecture:ARM920T Author:ce123(http://blog.csdn.net/ce123) 1.copy_from_user 在學習Linux核心驅動的時候,經常會碰到copy_from_user和c
linux核心中的get user和put user
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
淺析linux核心中的idr機制
分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!  
【轉】Linux 核心中的Device Mapper機制
轉自:https://www.ibm.com/developerworks/cn/linux/l-devmapper/index.html,寫的很通俗易懂,轉載學習下。 Device Mapper 是 Linux2.6 核心中支援邏輯卷管理的通用裝置對映機制,它為實現用於儲存資源管理的塊裝置驅動
linux核心中Makefile的使用
linux核心中Makefile 的作用是根據配置的情況,構造出需要編譯的原始檔列表,然後分別編譯,並把目的碼連結到一起,最終形成 Linux 核心二進位制檔案。 由於 Linux 核心原始碼是按照樹形結構組織的,所以 Makefile 也被分佈在
如何開啟linux核心中dev_dbg的開關
比如要開啟某個驅動中的dev_dbg,那麼需要在驅動檔案.c中這些行"<linux/device.h>"或者"<linux /platfom_device.h>"(device.h包含platform_device.h)之前定義DEBUG 如: #define DEBUG 1 #
Linux核心中的per-cpu變數
per CPU變數 per-CPU變數從字面上即可猜出它大概的含義,這種型別的變數實際上每個CPU都分配了一個該變數的副本。對於per-CPU的訪問幾乎不需要鎖定,因為每個CPU都工作在自己的副本上,另外per CPU變數還可以儲存在CPU自己的快取上,這樣就最大的優化訪問速度和減少
淺談linux核心中的I2c驅動(1)
相信瞭解過linux核心的人一定知道在linux核心中有一條非常重要的主線就是匯流排裝置驅動模型。 它是Linux驅動的精髓。不僅在我們今天要講的I2c驅動中存在,像usb,spi,I2s,platform等裝置中也是存在 的。而且在Linux核心的原始碼中,不能把匯流排單
淺談linux核心中的I2c驅動(2)
上篇文章將到了I2c驅動的中的i2c-s3c2410.c檔案,它在整個I2c驅動的架構中屬於最底層的。 總結一下它乾的事: A:找到裝置的資源 (通過平臺匯流排裝置驅動模型) B:使用裝置的資源 (硬體的操作) C:註冊裝置 (將裝置掛到I2c匯流排裝置連結串列
Linux核心中RAID5原始碼詳解之基本架構與資料結構
Linux核心中RAID5的基本架構與資料結構解析 眾所周知,早年的計算機儲存資料現在磁帶上,然後發展到了磁碟,然而僅僅是單個盤,速度和效能都不是很好,然是,要知道人類的聰明才智是連ET都想不到的,前輩們不斷的猜想,實驗來提高計算機的效能,於是磁碟陣列問世
[經典]Linux核心中ioremap對映的透徹理解
幾乎每一種外設都是通過讀寫裝置上的暫存器來進行的,通常包括控制暫存器、狀態暫存器和資料暫存器三大類,外設的暫存器通常被連續地編址。根據CPU體系結構的不同,CPU對IO埠的編址方式有兩種: (1)I/O對映方式(I/O-mapped) 典型地,如X86處理器為外設專門
Linux核心中的Proc檔案系統(一)
(1)/proc檔案系統的特點和/proc檔案的說明/proc檔案系統是一種特殊的、由軟體建立的檔案系統,核心使用它向外界匯出資訊,/proc系統只存在記憶體當中,而不佔用外存空間。/proc下面的每個
Linux核心中ioremap對映的透徹理解 .
幾乎每一種外設都是通過讀寫裝置上的暫存器來進行的,通常包括控制暫存器、狀態暫存器和資料暫存器三大類,外設的暫存器通常被連續地編址。根據CPU體系結構的不同,CPU對IO埠的編址方式有兩種: (1)I/O對映方式(I/O-mapped) 典型地,如X86處理器為外設專
Linux核心中的RCU機制 (詳解)
RCU的設計思想比較明確,通過新老指標替換的方式來實現免鎖方式的共享保護。但是具體到程式碼的層面,理解起來多少還是會有些困難。在《深入Linux裝置驅動程式核心機制》第4章中,已經非常明確地敘述了RCU背後所遵循的規則,這些規則是從一個比較高的視角來看,因為我覺