網(wǎng)站建設(shè)與管理方案書搜索引擎優(yōu)化論文
1.簡介
SMMUv3新增了命令和事件隊列(Command and Event queues),可選的PRI隊列,用于和軟件進行交互。軟件將要執(zhí)行的命令提交到命令隊列,比如預取配置、Invalidate STE命令等,SMMU從命令隊列取出命令并執(zhí)行。當命令不正確或配置出錯等錯誤發(fā)生時,SMMU將會將這些事件寫入到事件隊列,軟件從事件隊列取出事件進行處理。PRI隊列用于接收PCIe page requests。
2.循環(huán)隊列
命令和事件隊列基于循環(huán)隊列(circular queues)。循環(huán)隊列是基于內(nèi)存的生產(chǎn)者和消費者循環(huán)FIFO。生產(chǎn)者向FIFO中寫入任務(wù),消費者從FIFO中讀取1任務(wù),生產(chǎn)者的位置由PROD指針確定,表示下一個可以寫入的位置,消費者的位置由CONS指針確定,表示下一個可以讀取的位置,PROD指針和CONS指針保存在寄存器中。對于命令隊列,CPU為生產(chǎn)者,SMMU為消費者。對于事件隊列,SMMU為生產(chǎn)者,CPU為消費者。循環(huán)隊列生命周期如下圖所示,當隊列指針從隊列尾跳到隊列頭時,wrap值會變化。
- PROD.WR == CONS.RD and PROD.WR_WRAP == CONS.RD_WRAP,此時隊列空。
- PROD.WR > CONS.RD and PROD.WR_WRAP == CONS.RD_WRAP,生產(chǎn)者寫入任務(wù)。
- PROD.WR == CONS.RD and PROD.WR_WRAP == CONS.RD_WRAP,消費者讀取任務(wù),此時隊列空。
- PROD.WR < CONS.RD and PROD.WR_WRAP != CONS.RD_WRAP,生產(chǎn)者寫入任務(wù),PROD指針跳到了隊列頭。
- PROD.WR == CONS.RD and PROD.WR_WRAP != CONS.RD_WRAP,生產(chǎn)者繼續(xù)寫入任務(wù),此時隊列滿。
- PROD.WR > CONS.RD and PROD.WR_WRAP == CONS.RD_WRAP,消費者讀取任務(wù),CONS指針跳到了隊列頭。
- PROD.WR == CONS.RD and PROD.WR_WRAP == CONS.RD_WRAP,消費者繼續(xù)讀取任務(wù),此時隊列空。
3.命令
CPU將命令(Command)寫入命令隊列,SMMU從命令隊列中取出命令執(zhí)行。命令隊列中每個元素都為16字節(jié),采用小端字節(jié)序,開始的8位表示命令操作碼。SMMU總共定義了6種命令,分別為Prefetch、Configuration structure invalidation、TLB invalidation、ATS and PRI、DPT maintenance、Fault response and synchronization commands,具體的作用如下。
- Prefetch:將STE和CD等數(shù)據(jù)結(jié)構(gòu)預取到Cache中,可以提高地址轉(zhuǎn)換速度。
- TLB invalidation:維護TLB數(shù)據(jù)一致性。
- ATS and PRI:用于處理PCIe設(shè)備DMA地址轉(zhuǎn)換。
- DPT maintenance:主要用于維護頁表結(jié)構(gòu)的完整性和一致性,尤其是在多核系統(tǒng)或動態(tài)內(nèi)存管理場景中。
- Fault response and synchronization commands:用于處理Fault和同步命令。
下面只介紹常用的幾個,其他的參考SMMU Spec。
3.1.Prefetch
Prefetch命令可以讓SMMU預取和stream相關(guān)的配置和地址轉(zhuǎn)換數(shù)據(jù)。
3.1.1.CMD_PREFETCH_CONFIG
預取來自給定StreamID(以及當SSV == 1時的SubstreamID)流量所需的任何STE和CD配置結(jié)構(gòu)。
3.1.2.CMD_PREFETCH_ADDR
預取給定地址范圍內(nèi)的任何STE和CD配置結(jié)構(gòu)及TLB項。
3.2.Configuration structure invalidation
當軟件修改某些配置結(jié)構(gòu)(Stream table、CD table)后,需要向SMMU發(fā)送命令,確保invalidates緩存這些結(jié)構(gòu)的Cache。
3.2.1.CMD_CFGI_STE
invalidates StreamID關(guān)聯(lián)的STE Cache。
3.2.2.CMD_CFGI_STE_RANGE
invalidates StreamID關(guān)聯(lián)的多個STE Cache,Start = (StreamID & ~(2^(Range+1) - 1)。
End = Start + 2^(Range+1) - 1。
3.2.3.CMD_CFGI_CD
invalidates StreamID和SubstreamID關(guān)聯(lián)的一個CD Cache。該命令在改變TTBRx/ASID或者試能TBI時使用。
3.2.4.CMD_CFGI_CD_ALL
invalidates StreamID關(guān)聯(lián)的所有CD Cache。
3.3.Fault response and synchronization commands
當錯誤發(fā)生時,CPU需要向SMMU發(fā)送Fault response以處理錯誤。CPU提交的命令SMMU是異步執(zhí)行的,因此CPU需要提交synchronization command命令,獲取命令執(zhí)行結(jié)果。
3.3.1.CMD_RESUME
使用StreamID和STAG參數(shù),喚醒處于stalled狀態(tài)的事務(wù)。StreamID用于索引事務(wù),STAG參數(shù)定義事務(wù)喚醒后的行為。
Action (Ac) | Result |
---|---|
1 | 事務(wù)將被重試(Retry),其行為與第一次執(zhí)行時時相同。系統(tǒng)會重新查詢配置和地址轉(zhuǎn)換。此后,該事務(wù)可能繼續(xù)正常執(zhí)行,也可能再次觸發(fā)錯誤(Fault)。 |
0 | 事務(wù)將以Abort parameter(Ab)參數(shù)定義的方式終止(Terminate)。當Ab==0時,事務(wù)以RAZ/WI(Read-As-Zero/Write-Ignored)語義成功完成。當Ab==1時,系統(tǒng)會向客戶端報告中止/總線錯誤(abort/bus error)。 當SMMU_IDR0.TERM_MODEL == 1,Ab參數(shù)將被忽略,事務(wù)以abort終止。 Ab參數(shù)和CD.A(non-stalled terminated transactions)的配置類似。 |
3.3.2.CMD_SYNC
CMD_SYNC提供了以下的同步機制:
- 與CMD_SYNC提交至同一命令隊列的前序命令(類似于內(nèi)存屏障指令)。當CMD_SYNC執(zhí)行完成,同一隊列CMD_SYNC的前序命令必須執(zhí)行完成。
- 在CMD_SYNC之前終止的客戶端事務(wù)所對應事件記錄的可觀測性。
- 由地址轉(zhuǎn)換完成引起的HTTU更新。
當CMD_SYNC執(zhí)行完成后,會產(chǎn)生一個完成信號(ComplSignal),信號可以是中斷(可以采用MSI形式),也可以是WFE喚醒事件。完成信號的機制由參數(shù)CS決定,具體如下:
CS | Result |
---|---|
0b00 | SIG_NONE。CMD_SYNC執(zhí)行完成后不會有任何行為,MSIAddress、MSIData、MSIWriteAttributes參數(shù)被忽略。 |
0b01 | SIG_IRQ。CMD_SYNC執(zhí)行完成后會產(chǎn)生中斷。如果支持MSI,將會把MSIData寫到MSIAddress(物理地址)中觸發(fā)MSI中斷,通知PE CMD_SYNC執(zhí)行完成。如果MSIAddress非0,內(nèi)存屬性由MSIAttr決定。若不支持MSI,則MSIData、MSIAddress會被忽略。 |
0b10 | SIG_SEV。CMD_SYNC執(zhí)行完成后會給PE發(fā)送類似于SEV的事件。當SMMU_IDR0.SEV==1時,SIG_SEV才有效,否則效果和SIG_NONE一樣。此時CPU通過輪詢SMMU_CMDQ_CONS.RD判斷CMD_SYNC執(zhí)行是否完成,每次輪詢之間使用WFE命令等待SEV事件。 |
0b11 | Reserved。將會引發(fā)CERROR_ILL錯誤。 |
4.事件
SMMU將事件(Event)寫入事件隊列,CPU從事件隊列中取出事件處理。每個Event占用32字節(jié)。所有Event以小端字節(jié)序保存在Event隊列中。SMMU定義了19種標準事件,Event number范圍為0x1-0x13、0x20-0x21、0x24-0x25,用戶也可以自定義事件,Event number范圍為0xE0-0xEF。這些Event有一些公共的字段,具體如下表所示。
Common Fields | Reason |
---|---|
StreamID | 觸發(fā)Event對應的StreamID。 |
RnW | 觸發(fā)Event的事務(wù)讀寫屬性。0:寫,1:讀。 |
PnU | Privileged/Unprivileged。0:Unprivileged,1:Privileged。 |
InD | 觸發(fā)Event的訪問類型是指令訪問還是數(shù)據(jù)訪問。0:Data,1:Instruction。 |
InputAddr | 輸入到SMMU觸發(fā)Event的地址。根據(jù)場景和Event number,此字段可能被解釋為VA、IPA或PA,比如在地址轉(zhuǎn)換第一階段觸發(fā)F_TRANSLATION,InputAddr是VA。 |
SSV | SubstreamID是否有效標志。0:invalid,1:valid。 |
SubstreamID | 觸發(fā)Event對應的SubstreamID,只有SSV==1時有效。 |
S2 | 觸發(fā)Event的地址轉(zhuǎn)換階段。0:Stage 1 fault occurred,1:Stage 2 fault occurred。 |
CLASS | 觸發(fā)Event的操作的類別。 0b00: CD, CD fetch. 0b01: TTD, Stage 1 translation table fetch. 0b10: IN, Input address caused fault. 0b11: Reserved. |
NSIPA | Non-secure IPA。區(qū)分訪問安全還是非安全IPA空間觸發(fā)的Event。 |
GPCF | 頁表權(quán)限校驗Fault。 0: 由外部錯誤觸發(fā)的Fault,不是頁表權(quán)限觸發(fā)。 1: 由頁表權(quán)限觸發(fā)的Fault。 |
在Linux內(nèi)核中只處理和地址轉(zhuǎn)換相關(guān)的F_TRANSLATION、F_ADDR_SIZE、F_ACCESS、F_PERMISSION四種Event,下面也只介紹這4種Event。
4.1.F_TRANSLATION
F_TRANSLATION錯誤表示訪問地址在某一級地址轉(zhuǎn)換階段未通過由TxSZ/SLx定義的范圍檢查,或者地址位于一個已禁用的TTBx范圍內(nèi),又或者未能為該地址找到有效的轉(zhuǎn)換表描述符。
4.2.F_ADDR_SIZE
在某一級地址轉(zhuǎn)換階段,輸出的地址超出了該階段的有效地址空間范圍(由 xPS 定義),從而觸發(fā)的錯誤。具體觸發(fā)條件如下:
- 轉(zhuǎn)換過程中地址越界
- 當某級轉(zhuǎn)換(Stage1或Stage2)解析中間頁表和最后一級頁表描述符時,若輸出的地址超出了該轉(zhuǎn)換表關(guān)聯(lián)的有效物理地址空間xPS(由CD.IPS或STE.S2PS定義),則觸發(fā)此錯誤。
- 注意:如果TTB本身超出范圍(在轉(zhuǎn)換表遍歷開始前),則不會觸發(fā)此錯誤,而是會直接導致 C_BAD_CD(配置描述符無效)或 C_BAD_STE(STE 無效)。 - Stage 1 旁路轉(zhuǎn)換時的地址越界
- 如果Stage 1 bypass,則輸出地址 == 輸入地址。若該地址超出了硬件支持的地址范圍也會觸發(fā)此錯誤。
4.3.F_ACCESS
頁或塊描述符中AF == 0導致的訪問標志錯誤。如果支持并啟用了HTTU,則將帶有AF == 0的描述符修改為AF == 1,且不會上報該錯誤。
4.4. F_PERMISSION
頁表訪問權(quán)限錯誤。
參考資料
- Arm ? System Memory Management Unit Architecture Specification version 3.
- Linux Kernel 6.12.31 Source Code.