作者簡介
baron (網(wǎng)名:代碼改變世界ctw),九年手機(jī)安全/SOC底層安全開發(fā)經(jīng)驗(yàn)。擅長trustzone/tee安全產(chǎn)品的設(shè)計(jì)和開發(fā)
1.序言
帶著問題去學(xué)習(xí),關(guān)于cache的一些思考:1、L1/L2/L3 cache到底在哪里?L1/L2/L3 cache分別都是多大?2、L1/L2/L3 cache的組織形式都是怎樣的?n路組相連?3、你見過VIVT的cache嗎?你為什么要學(xué)習(xí)VIVT的cache?非常干擾你對(duì)cache的理解,還不如不學(xué)呢.4、那么cache是VIPT還是PIPT?還是在一個(gè)core中既有VIPT,也有PIPT?5、你要學(xué)習(xí)MESI的原理嗎?你能記得住嗎?你是不懂MESI,還是不懂cache架構(gòu)?6、MOESI又是啥玩意?現(xiàn)在主流的core是MESI,還是MOESI?7、MESI僅僅是一個(gè)協(xié)議,總得有硬件來執(zhí)行這個(gè)協(xié)議,硬件是誰?8、MESI這個(gè)協(xié)議有4個(gè)狀態(tài),這4個(gè)狀態(tài)記錄在哪里?9、L1/L2/L3 cache中,或者說core cache/cluster cache中,哪些cache的維護(hù)遵守了MESI協(xié)議,哪些沒有遵守?為什么這樣設(shè)計(jì)?10、cache line中的data是多少個(gè)字節(jié)?在分析問題時(shí),你為什么總是按照條件分析,16bytes的cache line是怎樣的,64bytes的cacheline是怎樣的?難道你不知道,現(xiàn)在主流的arm core的cache line全部都是64bytes?11、cache的TAG是什么玩意,里面都有什么?別說cache TAG是物理地址?12、cache line中又都有什么? 為什么沒有index?13、L2 cache到底是在core中,還是在cluster中?14、假設(shè)一塊內(nèi)存配置成了non-cacheable,為什么就不緩存到cache了?15、頁表entry的屬性中定義了cache的緩存策略,那如果disable mmu后,那么cpu讀寫內(nèi)存時(shí)候的緩存策略是什么?16、做為一名軟件工程師,對(duì)于L1/L2/L3 cache的緩存策略,哪些可以修改?哪些是硬件定死的不可以修改?而這些的替換策略又都是怎樣的?17、什么是inclusive cache?什么是exclusive cache?Strictly和Weakly呢?18、一些概念的理解,如CCI、SCU、DSU、ACE、CHI ?19、如何配置一個(gè)頁面的cacheable屬性?如何配置頁表的cacheable屬性?
2.前言
做為一名底層安全工程師、一名一線支持客戶的FAE,工作的內(nèi)容涉及到TF-A、TEE、TA、Linux Kernel、Linux native程序等眾多模塊,也會(huì)涉及到一些硬件模塊driver。在這些不同的硬件或系統(tǒng)軟件之中,有著不同的memory屬性的配置,不同的緩存策略,那么我們?cè)谶@多硬件多軟件通過share memory通信時(shí),就會(huì)遇到各種各樣的問題,其實(shí)很多時(shí)候,也都是客戶的靈魂一問,為了給客戶一個(gè)專業(yè)的感覺,身為FAE也不得不去弄懂底層深層次的原理....
本人不是什么專家,更不是什么的大佬,也就是看了一些arm文檔,加上自己的理解,然后總結(jié)出如下文章,當(dāng)然我在總結(jié)的時(shí)候,一切都以官方資料為準(zhǔn),盡量不瞎說不亂說,有些查不到的資料我求證了一些ASIC專家。其實(shí)cache同其它模塊(如MMU、異常、gic...)相比,cache應(yīng)該算上最難的,不過好在它的大多數(shù)行為都是硬件幫我們做好了,所以我們軟件就簡單了,但是越是硬件自動(dòng)的行為,對(duì)于我們軟件工程師理解起來就會(huì)吃力,因?yàn)榭床坏劫Y料看不到設(shè)計(jì),很多都得靠猜。
最后,希望這系列文章,能夠?qū)Υ蠹矣兴鶐椭:煤脤W(xué)習(xí)、天天向上,卷起來同志們。
說明:
本系列所講述的,都是以armv8/armv9架構(gòu)位基準(zhǔn),如有涉及執(zhí)行狀態(tài),則是aarch64. 如有涉及具體core,則是A710和A53
大多數(shù)內(nèi)容來自arm官方文檔、少部分咨詢了ASIC同事,再加上部分自己的理解...
3.為什么要用cache?
ARM 架構(gòu)剛開始開發(fā)時(shí),處理器的時(shí)鐘速度和內(nèi)存的訪問速度大致相似。今天的處理器內(nèi)核要復(fù)雜得多,并且時(shí)鐘頻率可以快幾個(gè)數(shù)量級(jí)。然而,外部總線和存儲(chǔ)設(shè)備的頻率并沒有達(dá)到同樣的程度??梢詫?shí)現(xiàn)可以與內(nèi)核以相同速度運(yùn)行的小片上 SRAM塊,但與標(biāo)準(zhǔn) DRAM 塊相比,這種 RAM 非常昂貴,標(biāo)準(zhǔn) DRAM 塊的容量可能高出數(shù)千倍。在許多基于 ARM 處理器的系統(tǒng)中,訪問外部存儲(chǔ)器需要數(shù)十甚至數(shù)百個(gè)內(nèi)核周期。
高速緩存是位于核心和主內(nèi)存之間的小而快速的內(nèi)存塊。它在主內(nèi)存中保存項(xiàng)目的副本。對(duì)高速緩沖存儲(chǔ)器的訪問比對(duì)主存儲(chǔ)器的訪問快得多。每當(dāng)內(nèi)核讀取或?qū)懭胩囟ǖ刂窌r(shí),它首先會(huì)在緩存中查找。如果它在高速緩存中找到地址,它就使用高速緩存中的數(shù)據(jù),而不是執(zhí)行對(duì)主存儲(chǔ)器的訪問。通過減少緩慢的外部存儲(chǔ)器訪問時(shí)間的影響,這顯著提高了系統(tǒng)的潛在性能。通過避免驅(qū)動(dòng)外部信號(hào)的需要,它還降低了系統(tǒng)的功耗
4.為什么要學(xué)習(xí)cache呢?
cache和我們軟件工程師有啥關(guān)系?其實(shí)在很多時(shí)候,硬件都會(huì)自動(dòng)去維護(hù)cache和內(nèi)存直接的一致性,這和我們軟件工程師都沒有太大的關(guān)系,所以很多時(shí)候我們也無需去理解cache的原理。但是實(shí)就是事實(shí),不管你有沒有理解,你都是一直在使用的。做為一名底層的軟件開發(fā)者,有些時(shí)候,你也不得不去主動(dòng)刷新cache,即軟件中維護(hù)內(nèi)存一致性 。那么一般什么時(shí)候需要主動(dòng)刷cache呢(軟件中維護(hù)內(nèi)存一致性) ? 以下便舉了幾個(gè)最常見的示例。
4.1 不同的Master硬件共享數(shù)據(jù)時(shí)
例如一個(gè)core和一個(gè)crypto engine硬件,在共享數(shù)據(jù)的時(shí)候。需要軟件主動(dòng)去invalid或flush cache的操作。
4.1.1 軟件中維護(hù)內(nèi)存一致性 – flush cache
4.1.2 軟件中維護(hù)內(nèi)存一致性 – invalid cache
4.2 不同的緩存策略的系統(tǒng)共享數(shù)據(jù)時(shí)
例如在一個(gè)TEE + linux的系統(tǒng)中,且兩個(gè)系統(tǒng)有著不同的緩存策略。如linux kernel中是outer cacheable,TEE中是non-cacheable
4.2.1 軟件中維護(hù)內(nèi)存一致性 – flush cache
4.2.2 軟件中維護(hù)內(nèi)存一致性 – invalid cache
5.怎么去刷cache呢?(軟件維護(hù)cache的一致性)
ARM提供了操作cache的指令, 軟件維護(hù)操作cache的指令有三類:
Invalidation:其實(shí)就是修改valid bit,讓cache無效。
Cleaning:清除cache中的data和TAG,這其實(shí)就是我們所說的flush cache,這里會(huì)將cache數(shù)據(jù)回寫到內(nèi)存,并清除dirty標(biāo)志
Zero:將cache中的數(shù)據(jù)清0.
那么一般什么時(shí)候需要軟件維護(hù)cache一致性呢?:(1)、當(dāng)有其它的Master改變的external memory,如DMA操作(2)、MMU的enable或disable的整個(gè)區(qū)間的內(nèi)存訪問,(3)、當(dāng)不同緩存策略的系統(tǒng)使用同一塊內(nèi)存通信時(shí),如REE enable了mmu,TEE disable了mmu.
針對(duì)第(2)點(diǎn),cache怎么和mmu扯上關(guān)系了呢?那是因?yàn)? mmu的開啟和關(guān)閉,影響了內(nèi)存的permissions, cache policies
5.1 cache一致性指令介紹
查閱armv8/armv9的aarch64體系中,定義了如下的緩存一致性操作指令指令太多,不太好記,然后我們總結(jié)如下:按照指令,分為:
IC : 操作instruction cache
DC : 操作data cache
按照操作,分為以下三類:
Invalidation:其實(shí)就是修改valid bit,讓cache無效。
Cleaning:清除cache中的data和TAG,這其實(shí)就是我們所說的flush cache,這里會(huì)將cache數(shù)據(jù)回寫到內(nèi)存,并清除dirty標(biāo)志
Zero:將cache中的數(shù)據(jù)清0.
Points的定義:其描述的是操作cache的范圍
Point of Coherency (PoC) :instruction、data、TLB訪問一致性的點(diǎn)
Point of Unification (PoU) :agents訪問內(nèi)存一致性的點(diǎn)
Point of Persistence (PoP) :和FEATDPB、FEATDPB2 feature相關(guān)
Point of Deep Persistence (PoDP) :訪問memory一致性的點(diǎn)
5.2 cache一致性指令的使用示例
5.3 操作系統(tǒng)中軟件維護(hù)cache一致性的API
在操作系統(tǒng)中,我們只需要調(diào)用相關(guān)的API即可,也無需牢記以上的維護(hù)cache一致性的命令。
比如在Linux Kernel 操作Cache的API如下所示:
linux/arch/arm64/mm/cache.S
linux/arch/arm64/include/asm/cacheflush.h
void __flush_icache_range(unsignedlong start, unsignedlong end);
int invalidate_icache_range(unsignedlong start, unsignedlong end);
void __flush_dcache_area(void*addr, size_t len);
void __inval_dcache_area(void*addr, size_t len);
void __clean_dcache_area_poc(void*addr, size_t len);
void __clean_dcache_area_pop(void*addr, size_t len);
void __clean_dcache_area_pou(void*addr, size_t len);
long __flush_cache_user_range(unsignedlong start, unsignedlong end);
void sync_icache_aliases(void*kaddr, unsignedlong len);
void flush_icache_range(unsignedlong start, unsignedlong end)
void __flush_icache_all(void)
原文標(biāo)題:深入學(xué)習(xí)Cache系列 1: 帶著幾個(gè)疑問,從Cache的應(yīng)用場景學(xué)起
文章出處:【微信公眾號(hào):Linux閱碼場】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
-
軟件
+關(guān)注
關(guān)注
69文章
4921瀏覽量
87396 -
開發(fā)
+關(guān)注
關(guān)注
0文章
370瀏覽量
40836 -
高速緩沖存儲(chǔ)器
+關(guān)注
關(guān)注
0文章
11瀏覽量
7509
原文標(biāo)題:深入學(xué)習(xí)Cache系列 1: 帶著幾個(gè)疑問,從Cache的應(yīng)用場景學(xué)起
文章出處:【微信號(hào):LinuxDev,微信公眾號(hào):Linux閱碼場】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論