請問ARMv8如何讀取cache line中的MOESI信息呢?

2023-09-08 15:15:44 來源:Arm精選

本文以Cortex-A53處理器為例,通過訪問 處理器中的 內部存儲單元(tag RAM和dirty RAM),來讀取cache line 中的MOESI信息。

Cortex-A53提供了一種通過讀取一些系統(tǒng)寄存器,來訪問Cache 和 TLB使用的一些內部存儲單元的機制。這個功能可以探查出當緩存中的數(shù)據(jù)與主存中的數(shù)據(jù)不一致時存在的問題。

此外,A64模式和A32模式的讀取方式不同:


【資料圖】

當處理器處于A64模式時,先通過一些只寫(write-only)寄存器來選擇具體的cache line和內存地址,然后通過只讀寄存器來讀取具體的tag信息。下圖為相關寄存器以及相關操作指令,需要注意的是,這些操作只在EL3時可用,如果在其他模式下使用這些指令,將會進入Undefined Instruction 異常。

當處理器處于A32模式下時,先通過一些只寫(write-only)CP15寄存器來選擇具體的cache line和內存地址,然后通過只讀CP15寄存器來讀取具體的tag信息。下圖為相關寄存器以及相關操作指令,需要注意的是,這些操作只在EL3時可用,如果在其他模式下使用這些CP15指令,將會進入Undefined Instruction 異常。

接下來,本文以Cortex-A53的Data cache為例,讀取其某個cache line的tag信息,其具體的步驟很簡單,分為兩步:

寫入Data Cache Tag ReadOperation Register,寫入的內容為具體的Set和way信息,通過way index和set index來定位到想要讀取的cache line。讀取相應的 Data Register 0 和 Data Register 1寄存器,通過對Data Register寄存器里面的數(shù)據(jù)進行解碼,來獲取tag 信息。其他信息,比如Data cache 的data信息,Instruction Cache的data或者tag信息,以及TLB的data信息,都可以用這種方式讀取得到。

Step1:將Set/way信息寫入Data Cache Tag Read Operation Register

首先,我們需要從一個虛擬地址(VA)中解析出Set index信息。

下圖為Cortex-A57的4-way組相連的32KB大小的data cache結構,其cache line大小也為64 bytes,從圖中可知,一個VA可以被分成幾個部分:Tag,Set index,word index以及byte index。其中Set index = VA[13:6]。

在另一個實例中,32KB大小的4-way組相連data cache,cache line大小為32 bytes,其Set index = VA[12:5]:

Cortex-A53的Data cache為4-way 組相連結構。假設其為32KB,一個cache line的大小為64 bytes,我們就可以求出該data cache中有 32 KB / 64 B / 4 = 2^7 = 128個set(組),也就是說至少需要7個bit才能完整解析出具體的set index。如下圖所示,可以通過公式:

S = log2(Data cache size / 4).

來計算出Set index的范圍:Set index = VA[12:6]。

由于是4-way 組相連結構,cache line 可以存在與任意一個way中,所以我們的cache way可能為0,1,2,3中任意一個數(shù)字。

求得了set和way的index后,需要對其進行編碼,然后寫入到Data Cache Tag Read Operation Register寄存器中。其編碼規(guī)則如下圖所示,只需將Set和way的值寫入對應的bit中即可,其中Rd[5:3]為cahche double word數(shù)據(jù)的偏移量,由于本次示例是讀取tag信息,所以Rd[5:3]為0即可。

所以我們要寫入Data Cache Tag Read Operation Register的Rd的值可以通過以下代碼獲取:

unsigned int get_Rd_data(int * VA, way_num){  unsigned int set_way_index = VA | 0x1FC0; //get way index, VA[12:6]  set_way_index |= way_num < 30; //way_num could be 0,1,2,3   return set_way_index;}

Rd中除了Set和way信息,其他值均為0,0x1FC0為VA[12:6]全為1的情況:

然后我們使用CP15寄存器將Rd的值寫入,假設Rd為R0:

MCR p15, 3, r0, c15, c2, 0   ; r0 = get_Rd_data(VA,way_num)

Step2:讀取Data Register 1和Data Register 0數(shù)據(jù)并解碼

將Set/way信息寫入Data Cache Tag Read Operation Register 后,相當于選擇了想要操作的cache line,接下來我們將讀取Data Register 1和Data Register 0的數(shù)據(jù)來獲取該cache line里的tag信息,除了tag信息外,我們還可以從Data Register 1和Data Register 0兩個寄存器中獲取:

MOESI 狀態(tài)信息outer內存屬性valid 信息

可獲得的信息具體見下圖:

需要注意的是,如果是想獲取MOESI狀態(tài)信息,則需要兩個寄存器配合使用,即讀取Data Register 0 [1:0]以及Data Register 1 [30:29] ,Data Register 0 [1:0]里的為來自Dirty RAM的部分狀態(tài)信息,Data Register 1 [30:29]里的為來自tag RAM的部分MOESI信息,

其具體的組合見下圖:

比如讀取到的Data Register 0 [1:0]為1,以及Data Register 1 [30:29]也為1,根據(jù)上圖的組合關系,可知當前cache line的MOESI狀態(tài)為 SharedDirty(O)。

示例代碼如下:

; step 1: write set index and way num into Data Cache Tag Read Operation RegisterMCR p15, 3, r0, c15, c2, 0   ; r0 = get_Rd_data(VA,way_num); step 2: read Data Register 1 and Data Register 0MCR p15, 3, r1, c15, c0, 0   ;r1 =  Data Register 0 MCR p15, 3, r2, c15, c0, 1   ;r2 =  Data Register 1

標簽:

上一篇:驅動器共模電流路徑與數(shù)學模型分析
下一篇:最后一頁