powerpc e500 實現有兩級 tlb,即:l1 tlb 和 l2 tlb。l1 tlb 可以理解為 l2 tlb 的部分快取。訪問 l1 tlb 的效率要比 l2 的效率高,相應的實現的花費也就高。l1 tlb 由硬體維護,不可程式設計精確控制。程式設計師可控制的一般是l2 tlb,因此以下的討論皆針對 l2 tlb,為方便簡稱其為 tlb。
由於l1 mmu只是乙個l2mmu的乙個子集,硬體負責自動更新,因此我們可以就可以通過程式設計控制l2 mmu中的tlb就能達到操作tlb的目的。
通過對l2 mmu的tlb程式設計,我們可以進行根據虛擬位址查詢匹配的tlb entry,建立虛擬頁<—>物理頁對映,修改tlb entry中的屬性,無效tlb等等操作,這樣的方式讓powerpc e500的mmu更加靈活。
說明:我們用程式控制找到的entry指的是l2 mmu 中tlb中的entry index。
指令:tlbsx ra,rb
準備:(1) 首先配置mas6暫存器:spid0域和sas域;
(2) 把我們需要尋找的虛擬位址放到ra+rb中(一般直接放到rb中,ra置0);
(3) 執行tlbsx ra,rb指令;
執行:
指令tlbsx會根據mas6、ra+rb的值,進行如下匹配:對l2 mmu中tlb0和tlb1的每乙個entry進行查詢:
(1)entry中的v域是否有效;
(2)mas6、ra+rb與entry對應的字段進行匹配:spid0 == tid,sas == ts, epn == (ra+rb) (上面的「==」表示匹配,不一定是相等,例如:enp == (ra+rb) ,這裡需要根據entry的size域來確定epn的位數。epn總共20位,所以對應的最小頁大小是4k,即這20位都作為虛擬頁號;如果size指示頁大小為4m ,即一頁佔22位,那麼epn只有10位有效,這時秩序匹配ra+rb的高10位就可以了)
(3)若mas6、ra+rb匹配到某乙個entry,並且v域有效,則說明我們匹配成功,也就是命中,否則沒有匹配到任何entry表示不命中。
輸出:
(1)若tlbsx命中:將命中的entry,包括entry index輸出到如下暫存器的相應欄位中。mas0 ~ mas3:mas1[v] = 1,mas0[tlbsel] = 命中的是tlb0/tlb1, mas0[esel]命中的entry的index或者tlb0的哪一路。
(2)若沒有命中,則mas1[v] = 0,mas2[rpn] 為 0
舉例:
/* find the index of the entry we're executing in */
bl invstr /* find our address */
mfmsr r7
mfspr r7, sprn_pid0
slwi r7,r7,16
or r7,r7,r4
mtspr sprn_mas6,r7 /* 設定mas6的sas */
tlbsx 0,r6 /* search msr[is], spid=pid0 */
上面的**表示將我們正在執行的 標號invstr處的位址放到r6中,並在tlb的當前(is)位址空間中查詢r6這個位址對應的entry。
(1) 通過mas0選擇我們要讀取的entry。
配置mas0[tlbsel]指定讀tlb0還是tlb1;
配置mas0[esel]指定命中是哪乙個entry,若選擇的是tlb0,還需要先借助epn[45:51]來進行索引組,然後通過esel則來路選確定具體的entry項。
(2) 執行tlbre,根據上面的資訊讀取指定的tlb entry。
過程:
li r6,0 /* set entry counter to 0 */
lis r7,0x1000 /* set mas0(tlbsel) = 1 */
rlwimi r7,r6,16,4,15 /* setup mas0 = tlbsel | esel(r6) */
mtspr sprn_mas0,r7
tlbre
上述**的目的是讀取tlb1中的entry0
和讀tlb類似,要寫某個tlb entry首先要定位這個entry,然後將各個mas0中的對應的各個域寫入到這個entry。
指令:tlbwe
準備:
(1) 通過mas0選擇我們要讀取的entry。
配置mas0[tlbsel]指定讀tlb0還是tlb1;
配置mas0[esel]指定命中是哪乙個entry,若選擇的是tlb0,還需要先借助epn[45:51]來進行索引組,然後通過esel則來路選確定具體的entry項。
(2) 準備好我們需要寫到entry中內容。填寫好各個mas暫存器中與entry對應的各個域,如mas2[epn],mas3[rpn]等。
(3) 執行tlbwe,根據上面的資訊找到指定的tlb entry,並將這個entry的資訊寫到各個mas暫存器中。
過程:
tlbwe指令根據mas0中tlbsel和esel域來定位某個entry,並把entry中內容讀出到各個mas暫存器的相關域中。
舉例:
li r6,0 /* set entry counter to 0 */
lis r7,0x1000 /* set mas0(tlbsel) = 1 */
rlwimi r7,r6,16,4,15 /* setup mas0 = tlbsel | esel(r6) */
mtspr sprn_mas0,r7 /* 找到tlb1的entry0 */
mfspr r7,sprn_mas1
rlwinm r7,r7,0,2,31 /* clear mas1 valid and iprot */
mtspr sprn_mas1,r7
tlbwe /* 寫tlb */
上述**修改(清除)tlb1中entry0的valid和iporot域。
(1) ea[32:51] 用於匹配 tlb 項 (組選 + epn 匹配),其不進行 pid 和 as 的比較,則若同一組內有相同的 epn,皆會將其置無效。
(2) ea[60] 用於選擇操作的物件是 tlb0 還是 tlb1,類似 mas0[tlbsel];
(3) ea[61] 為 1 則置無效 tlb0 或 tlb1 的所有項
(4) 若 hid1[abe] = 1 則該無效操作亦廣播給其它 core,置無效相應的項。
注意:若tlb1的某項entry 的iprot域為1,可以不受tlbivax的影響。
舉例:
/* 當前程序的data位址空間中,尋找虛擬位址為0xc0000000的tlb entry */
lis r6 , 0xc0000000@h
ori r6 , r6 , 0xc0000000@l
mfmsr r7
rlwinm r4,r7,27,31,31 /* extract msr[ds] */
mfspr r7, sprn_pid0
slwi r7,r7,16
or r7,r7,r4
mtspr sprn_mas6,r7
tlbsx 0,r6 /* search msr[ds], spid=pid0 */
/* 設定這個entry的iprot域,保證後面的tlbivax指令不會讓自己無效 */
mfspr r7,sprn_mas0
rlwinm r3,r7,16,20,31 /* extract mas0(entry) */
mfspr r7,sprn_mas1 /* insure iprot set */
oris r7,r7,mas1_iprot@h
mtspr sprn_mas1,r7
tlbwe
/* 除了我們設定的0xc0000000對應的entry,tlb0和tlb1中的其他的entry全部置無效(除非某個其他的entry中也設定了iprot位) */
/* invalidate tlb0 */
li r6,0x04
tlbivax 0,r6
tlbsync
/* invalidate tlb1 */
li r6,0x0c
tlbivax 0,r6
tlbsync
看我是如何嚴辭拒絕同學借錢的
看我是如何嚴辭拒絕同學借錢的 朋友同學之間借錢應急一下本無可非議,但現在許多經驗和歷史教訓告訴我們,借錢給他人就等於失去這個朋友,最後弄得自己也很鬱悶甚至是惱怒,所以在這裡轉一篇關於如何拒絕朋友間借錢的文章,希望筒子們以後面對此類現象一定要痛下決心勇敢說 不!先自己誇自己兩句吧 我一向為人還算忠厚,...
張本偉 IT人如何收入500萬?
因為最近房價再次猛漲,很多年輕人望房興嘆,一套150公尺的房子,好點位置的就要小500萬,可是,500萬?對於大多數it人來講,似乎那麼遙遠,所以,我覺得還是寫這個更實惠的話題,分享一下周圍看到的it人是如何實現500萬收入的。先看看現實 如果你是一名工作3年技術人員,今年25歲,之前的3年工作,就...
cat日誌 搜尋 大日誌,看我如何對付你
在伺服器介面測試中,我們經常會和各種日誌打交道。一旦測試時服務端出現了問題,而單憑服務端的日誌又不能發現問題原因的時候,往往開發要向我們測試人員詢問客戶端這邊的情況,希望看看我們能不能提供一些有用資訊,如錯誤返回內容,錯誤發生時間,哪些用例會出現問題等等。這時就需要我們來查詢測試時的日誌,從中篩選出...