一、序言
1、序言
帶著問(wèn)題去學(xué)習(xí),關(guān)于異常/中斷的一些思考:
(1)、在如下的一個(gè)大系統(tǒng)種,cpu正在optee os中運(yùn)行,突然來(lái)了一個(gè)想給Linux Kernel處理的中斷(如一個(gè)藍(lán)牙中斷),那么此時(shí)的軟硬件流程是怎樣的?

(2)、在上述的大系統(tǒng)中,你的Linux Kernel、optee os、hypervisor、ATF系統(tǒng)中都有異常向量表,那么當(dāng)一個(gè)中斷到來(lái)時(shí),是跳轉(zhuǎn)到哪個(gè)系統(tǒng)中的向量表呢
(3)、什么是中斷嵌套?怎樣可以支持中斷嵌套?什么是中斷搶占?什么是中斷優(yōu)先級(jí)?什么是運(yùn)行中斷優(yōu)先級(jí)?
(4)、什么是FIQ?FIQ和IRQ的關(guān)系是什么?
(5)、當(dāng)來(lái)了一個(gè)中斷,是如何跳轉(zhuǎn)到向量表的?中間經(jīng)過(guò)了怎樣的路由?
(6)、當(dāng)你調(diào)用了svc/hvc/smc指令后,cpu是如何跳轉(zhuǎn)到你期望的目標(biāo)地址的?
(7)、同步異常有哪些,異步異常有哪些,哪些優(yōu)先級(jí)是一樣的,哪些優(yōu)先級(jí)是不一樣的?
(8)、異常向量表存放在哪里?為什么會(huì)有人說(shuō)放在0x00000000處?
(9)、什么是interrupt is asserted ?什么是interrupt is taken ?什么是PE Acknowledge this interrupt ?target 、routing又是什么意思?target from和target to呢?
做為一名底層安全工程師、一名一線支持客戶的FAE,工作的內(nèi)容涉及到TF-A、TEE、Linux Kernel、hypervisor、SPM等眾多模塊,cpu(或PE或core或PC)也會(huì)在這眾多模塊之間跳來(lái)跳去,由于這些代碼大多數(shù)都是開(kāi)源的,都是別人寫好的,其實(shí)很多時(shí)候,也無(wú)需去看其底層的設(shè)計(jì)原理。但做為一名FAE,會(huì)遇到客戶的靈魂一問(wèn),為了給客戶一個(gè)專業(yè)的感覺(jué),不得不去弄懂底層深層次的原理. 另外,有些時(shí)候遇到了性能相關(guān)問(wèn)題,不懂底層的設(shè)計(jì)原理,也許就無(wú)法分析這類問(wèn)題。
本人不是什么專家,也不是什么的大佬,也就是看了一些arm文檔,加上自己的理解,然后總結(jié)出如下文章,當(dāng)然我在總結(jié)的時(shí)候,一切都以官方資料為準(zhǔn),盡量不瞎說(shuō)不亂說(shuō)。。
最后,希望這系列文章,能夠?qū)Υ蠹矣兴鶐椭?。好好學(xué)習(xí)、天天向上,卷起來(lái)同志們。
說(shuō)明:
本系列所講述的,都是以armv8-aarch64/armv9架構(gòu)位基基礎(chǔ),Linux Kernel 5.10、optee3.16、TF-A 2.5
大多數(shù)內(nèi)容來(lái)自arm官方文檔、很小很小部靠猜測(cè),再加上部分自己的理解...
2、學(xué)習(xí)目標(biāo)

理解整個(gè)中斷的數(shù)據(jù)流,從peripheral到gic到core再到操作系統(tǒng)軟件
了解中斷的產(chǎn)生、中斷的標(biāo)記、中斷的路由、中斷的Master,以及操作系統(tǒng)對(duì)中斷的處理
了解從peripheral產(chǎn)生中斷后,有哪些是硬件自動(dòng)的行為,有哪些是架構(gòu)推薦定義的軟件流程,以及各類操作系統(tǒng)軟件中的處理流程
本系列文章主要講述圖中的3和4,主要包含以下文章:01-armv8/armv9中斷系列詳解-序言 02-armv8/armv9中斷系列詳解-硬件基礎(chǔ)篇 03-armv8/armv9中斷系列詳解-中斷示例展示(不含虛擬化部分) 04-armv8/armv9中斷系列詳解-中斷示例展示(虛擬化部分) 05-armv8/armv9中斷系列詳解-optee運(yùn)行時(shí)來(lái)了一個(gè)REE(linux)中斷–代碼導(dǎo)讀 06-armv8/armv9中斷系列詳解-軟件篇-Linux kernel中斷相關(guān)軟件導(dǎo)讀
二、硬件基礎(chǔ)篇
1 中斷的定義
有人說(shuō),中斷就包含IRQ和FIQ,其實(shí)這是不準(zhǔn)確的,準(zhǔn)確的說(shuō)法應(yīng)該是:產(chǎn)生到aarch64的異步異常(包括IRQ, FIQ, SError) 可看作中斷。官方文檔原話 :IntheArmv8-A architecture,asynchronous exceptions that are taken toAArch64state are also knownasinterrupts.
2 FIQ和IRQ
有人說(shuō)FIQ是快速中斷, FIQ比IRQ具有較高的優(yōu)先級(jí),而且他還能提出ARM官方文檔來(lái)證明他說(shuō)的正確性:

其實(shí),這也是錯(cuò)誤的!
正確的說(shuō)法是FIQ和IRQ具有同樣的優(yōu)先級(jí)(默認(rèn)的情況下,我們只討論armv8-aarch64和armv9)

3 中斷術(shù)語(yǔ)的介紹

SPIs(Share Periphral Interrupts)中斷進(jìn)來(lái)之后,由inactive狀態(tài)變成pending,此時(shí)中斷標(biāo)記為IRQ/FIQ,這是也就是中斷assert了,然后該中斷會(huì)根據(jù)HCR/SCR等的配置進(jìn)行路由(路由到哪個(gè)Exception Level等),這個(gè)過(guò)程也就target,也可以叫做routing。路由之后,在部分場(chǎng)景下還會(huì)再檢查PSTATE的MASK位,接下來(lái)就是PE acknowledge了,此時(shí)也就是中斷被taken了。PE acknowledge后,cpu interface會(huì)將該中斷置為Active.
4 gic中斷控制器的介紹
(注意:本文重點(diǎn)介紹armv8/armv9異常中斷,不會(huì)展開(kāi)介紹gic,這里只是帶一下簡(jiǎn)單概念)gic中斷控制器有眾多版本,gicv2/gicv3/gicv4是gic的架構(gòu),gic500/gic600是具體的gic IP。而在armv8/armv9中,基本都是使用的gicv3/gicv4。如下圖所示,每一個(gè)core都定義了,它說(shuō)使用的gic架構(gòu)。

gic中斷控制器與core連接的硬件框圖

5 Core中的中斷控制器接口的介紹
在gicv2中,gic中斷控制器將中斷信號(hào)(irq,fiq,serror)直接以signal的方式發(fā)送給core。而在gicv3中,gic的組件發(fā)生變化,將gic的cpu internface接口做到了core中,在這種情況下,gic將中斷信號(hào)通過(guò)AXI Stream發(fā)送給core(cluster),然后cpu interface再繼續(xù)發(fā)送irq/fiq/serror信息。

6 同步異常和異步異常的概念
6.1、同步異常和異步異常的定義
具備以下3個(gè)行為的稱之為同步異常:? The exception is generated as a result of direct execution or attempted execution of an instruction.? The return address presented to the exception handler is guaranteed to indicate the instruction that caused the exception.? The exception is precise
其實(shí)就是說(shuō):
異常是由執(zhí)行或嘗試執(zhí)行指令產(chǎn)生的
產(chǎn)生異常的那個(gè)位置是確定的,即每次執(zhí)行到“那個(gè)指令處”就會(huì)產(chǎn)生
異常是precise的
具備以下3個(gè)行為的稱之為異步異常::? The exception is not generated as a result of direct execution or attempted execution of the instruction stream.? The return address presented to the exception handler is not guaranteed to indicate the instruction that caused the exception.? The exception is imprecise.
其實(shí)就是說(shuō):
異常不是由執(zhí)行或嘗試執(zhí)行指令產(chǎn)生的
產(chǎn)生異常的那個(gè)位置不是確定的,即不知道執(zhí)行到哪里,就產(chǎn)生了異常
異常是imprecise的
那么precise 和 imprecise 又是什么意思呢??

比較繞、比較難懂,咱們換一個(gè)說(shuō)法:按照預(yù)期產(chǎn)生的異常稱之precise,反之imprecise
6.2、系統(tǒng)中有哪些異步異常?
其實(shí)主要就是:irq, fiq, SError
Physical interrupts Are signals sent to the PE from outside the PE. They are:
SError. System Error.
IRQ.
FIQ.
Virtual interrupts Are interrupts that software executing at EL2 can enable and make pending. A virtual interrupt is taken from EL0 or EL1 to EL1. Virtual interrupts have names that correspond to the physical interrupts:
vSError.
vIRQ.
vFIQ
6.3、系統(tǒng)中有哪些同步異常?
嘗試執(zhí)行UNDEFINED指令產(chǎn)生的任何異常,包括:(1)、嘗試在不適當(dāng)?shù)漠惓<?jí)別執(zhí)行指令。(2)、當(dāng)指令被禁用時(shí)嘗試執(zhí)行指令。(3)、嘗試執(zhí)行尚未分配的指令位模式。
非法執(zhí)行狀態(tài)異常。這些是由嘗試執(zhí)行指令引起的PSTATE.IL為 1,(詳細(xì)可參考D1-2486 頁(yè)上的AArch64 狀態(tài)的非法返回事件)
使用未對(duì)齊的 SP 導(dǎo)致的異常。
嘗試使用未對(duì)齊的 PC 執(zhí)行指令導(dǎo)致的異常。
由異常生成指令SVC、HVC或SMC引起的異常。
嘗試執(zhí)行系統(tǒng)寄存器定義為被捕獲到更高的異常級(jí)別。(詳細(xì)可參考可配置的指令使能和禁止,在D1-2510 頁(yè))
由內(nèi)存地址轉(zhuǎn)換系統(tǒng)生成的指令中止與嘗試相關(guān)聯(lián)從產(chǎn)生故障的內(nèi)存區(qū)域執(zhí)行指令。
內(nèi)存地址轉(zhuǎn)換系統(tǒng)生成的數(shù)據(jù)中止與嘗試讀取或?qū)懭氘a(chǎn)生故障的內(nèi)存。
由地址未對(duì)齊引起的數(shù)據(jù)中止。
如果實(shí)施FEAT_MTE2,則由標(biāo)記檢查故障引起的數(shù)據(jù)中止。。
所有調(diào)試異常:(1)、Breakpoint Instruction exceptions. (2)、Breakpoint exceptions. (3)、Watchpoint exceptions. (4)、Vector Catch exceptions. (5)、Software Step exceptions.
在支持捕獲浮點(diǎn)異常的實(shí)現(xiàn)中,由捕獲的IEEE 浮點(diǎn)異常引起的異常
在某些實(shí)現(xiàn)中,外部中止。外部中止是失敗的內(nèi)存訪問(wèn),包括訪問(wèn)地址轉(zhuǎn)換期間發(fā)生的內(nèi)存系統(tǒng)的那些部分。
7 軟件對(duì)中斷的處理流程
正常情況下,當(dāng)一個(gè)中斷(異常)進(jìn)來(lái)之后,PE(cpu)跳轉(zhuǎn)到中斷向量表,在中斷向量表中會(huì)再次調(diào)用C語(yǔ)言函數(shù),完成中斷的處理,流程圖如下所示:

ARM Core支持中斷搶占,當(dāng)一個(gè)中斷正常處理的時(shí)候,可能又觸發(fā)了一個(gè)高優(yōu)先級(jí)的中斷,示例如下所示:

思考你所用的操作系統(tǒng)就真的支持中斷嵌套嗎?如果想支持中斷嵌套,需要滿足哪些條件呢?后文會(huì)有詳細(xì)介紹。
8 向量表基地址寄存器的介紹
armv8定義了VBAREL1、VBAREL2、VBAR_EL3三個(gè)基地址寄存器


思考:1、VBAREL1、VBAREL2、VBAREL3寫入的基地址,是物理地址還是虛擬地址?2、基地址不再放0x00000000的位置嗎?3、異常向量表中,沒(méi)有reset offset了?4、異常向量表中的每一個(gè)offset為啥是0x80(128)地址空間?以前是多少?5、VBARELx中,為啥末尾11個(gè)bit是reserved?
9 中斷向量表的介紹

我們可以看出,實(shí)際上有四組表,每組表有四個(gè)offset,分別對(duì)應(yīng)sync,IRQ,F(xiàn)IQ和serror。
如果發(fā)生異常后并沒(méi)有exception level切換,并且發(fā)生異常之前使用的棧指針是SP_EL0,那么使用第一組異常向量表。
如果發(fā)生異常后并沒(méi)有exception level切換,并且發(fā)生異常之前使用的棧指針是SP_EL1/2/3,那么使用第二組異常向量表。
如果發(fā)生異常導(dǎo)致了exception level切換,并且發(fā)生異常之前的exception level運(yùn)行在AARCH64模式,那么使用第三組異常向量表。
如果發(fā)生異常導(dǎo)致了exception level切換,并且發(fā)生異常之前的exception level運(yùn)行在AARCH32模式,那么使用第四組異常向量表。
另外我們還可以看到的一點(diǎn)是,每一個(gè)異常入口不再僅僅占用4bytes的空間,而是占用0x80 bytes空間,也就是說(shuō),每一個(gè)異常入口可以放置多條指令,而不僅僅是一條跳轉(zhuǎn)指令
注意,到了armv9上,增加了 FEAT_DoubleFault之后,異常向量表稍微變化了一丁點(diǎn)變化,如圖中的標(biāo)注所示:

也就是說(shuō),當(dāng) FEAT_DoubleFault開(kāi)啟之后,且 SCR_EL3.EASE比特設(shè)置為1, 那么此時(shí)target到EL3的 Synchronous External abort將會(huì)跳轉(zhuǎn)到Serror offset。

在中斷產(chǎn)生之后,PC(或PE 或 Core 或 cpu)將跳轉(zhuǎn)到VBAR + 中斷offset處。事實(shí)上在armv8-aarch64或armv9體系中,有3個(gè)VBARELx寄存器,另外對(duì)于VBAREL1雖然只有一個(gè),但是在不同Security狀態(tài)的操作系統(tǒng)中,有著不同的cpu context,即也是可以看做成兩份。如果是要考慮虛擬化,那么VBAREL2可能也會(huì)有兩份,VBAREL1可能會(huì)有多份。

如下,是在不考慮EL2/虛擬化的時(shí)候,畫的一張向量表總截圖,即當(dāng)一個(gè)中斷來(lái)時(shí),硬件會(huì)自動(dòng)選擇哪一個(gè)VBAR_ELx寄存器,硬件會(huì)自動(dòng)選擇哪一組向量表,硬件會(huì)自動(dòng)選擇哪一個(gè)offset

10 中斷進(jìn)入和中斷退出時(shí)的硬件自動(dòng)行為
10.1 當(dāng)異常進(jìn)來(lái)之后ARM CORE的硬件自動(dòng)的行為(Exception entry)
[for common]
PE(即當(dāng)前PSTATE)狀態(tài)保存在目標(biāo)異常級(jí)別的SPSR_ELx中
返回地址保存在目標(biāo)異常級(jí)別的ELR_ELx中
所有PSTATE .{D, A, I, F} 都設(shè)置為 1。---即關(guān)閉了所有中斷
所選的堆棧指針寄存器是目標(biāo)異常級(jí)別的專用堆棧指針寄存器---即使用sp_elx
執(zhí)行移動(dòng)到目標(biāo)異常級(jí)別,并從異常向量定義的地址開(kāi)始---即跳轉(zhuǎn)到VBAR_ELx
[for 同步異常]
如果異常是同步異?;?SError 中斷,則描述原因的信息, 異常保存在目標(biāo)異常級(jí)別的ESR_ELx中。
如果指令中止異常、數(shù)據(jù)中止異常、PC 對(duì)齊錯(cuò)誤異常或Watchpoint異常,且目標(biāo)異常是aarch64, 錯(cuò)誤的虛擬地址保存在FAR_ELx 中。(Instruction Abort exception, Data Abort exception, PC alignment fault exception, or a Watchpoint exception )
如果指令中止異常,或數(shù)據(jù)中止異常被帶到 EL2 并且故障是與第 2 階段轉(zhuǎn)換,故障 IPA 保存在HPFAR_EL2 中
[for Serror]
對(duì)于物理 SError 中斷異常,在以下任一情況下,物理 SError 的掛起狀態(tài)將被清除 SError 中斷是邊沿觸發(fā)的。FEAT_DoubleFault已實(shí)現(xiàn) 如果Reliability, Availability, and Serviceability Extension被實(shí)施,并且在采取 SError 時(shí)中斷,記錄在ESR_ELx 中的綜合癥指示除IMPLEMENTATION之外的 SError定義或未分類的 SError 中斷綜合癥
對(duì)于虛擬 SError 中斷異常,虛擬 SError 的掛起狀態(tài),HCR_EL2.VSE位清零
[for FEAT]
PSTATE .SSBS 設(shè)置為SCTLR_ELx .DSSBS的值
如果FEAT_UAO實(shí)現(xiàn),PSTATE .UAO被設(shè)置為0
如果FEAT_MTE實(shí)現(xiàn),PSTATE .TCO設(shè)置為1
如果實(shí)現(xiàn)了FEATBTI,從 AArch64 到 AArch64 的異步異常,PSTATE .BTYPE 被復(fù)制到SPSRELx .BTYPE,然后設(shè)置為 0
如果實(shí)現(xiàn)了FEATBTI,在將某些類型的同步異常從 AArch64 轉(zhuǎn)移到 AArch64 時(shí),PSTATE .BTYPE 復(fù)制到SPSRELx .BTYPE 然后設(shè)置為 0 這些類型的同步異常是:軟件步驟異常。PC 對(duì)齊錯(cuò)誤異常。指令中止異常。斷點(diǎn)異?;虻刂菲ヅ湎蛄坎东@異常。非法執(zhí)行狀態(tài)異常。軟件斷點(diǎn)異常。分支目標(biāo)異常。
如果FEATIESB被實(shí)現(xiàn),當(dāng)有效數(shù)值的的SCTLRELx .IESB位在目標(biāo)異常level為1,PE插入錯(cuò)誤同步事件
10.2 當(dāng)異常退出時(shí)ARM CORE的硬件自動(dòng)的行為(Exception return)
(On executing an Exception return instruction at ELx)
PC從ELR_ELx恢復(fù)
PSTATE從SPSR_ELx恢復(fù)
11中斷的標(biāo)記
在gicv3中斷控制器中,對(duì)中斷進(jìn)行了分組:Group0、Secure Group1、Non-secure Group1。當(dāng)一個(gè)中斷進(jìn)來(lái)的時(shí)候,cpu interface會(huì)根據(jù)中斷的分組類型和當(dāng)前PE的security狀態(tài)來(lái)決定是標(biāo)記為IRQ還是FIQ

12 中斷的路由
我們知道系統(tǒng)中有三個(gè)基地址VBAREL1、VBAREL3、VBAREL1(secure),那么到底是使用哪一個(gè)呢?由Routing when both EL3 and EL2 are implemented 表來(lái)決定,中斷routing到了EL1則使用VBAREL1,routing到了EL3則使用VBAREL3,routing到了secure EL1則使用VBAREL1(secure)

為了更直觀的理解,總結(jié)成了下面的一個(gè)流程圖:

13 中斷的MASK(屏蔽)
在PSTATE中,A/I/F比特分別可以對(duì)SError、IRQ、FIQ進(jìn)行MASK
SError :PSTATE.A
IRQ :PSTATE.I
FIQ :PSTATE.F
但是在有些場(chǎng)景下,MASK將會(huì)失效,如在一些中斷被強(qiáng)制target到EL3的配置下,中斷的taken就不在關(guān)心PSTATE的mask位了。
以下表格做出了詳細(xì)的說(shuō)明:

其中:
A 表示 中斷的taken 將忽略 PSTATE的MASK位
B 表示 中斷的taken 不會(huì)忽略 PSTATE的MASK位,如果MASK了,就不會(huì)taken了。
C 表示 中斷不會(huì)被
A/B是 描述serror且和FEAT_DoubleFault相關(guān)的,暫不介紹
14 中斷路由(信號(hào)流)的總結(jié)
當(dāng)peripheral產(chǎn)生一個(gè)中斷后,PE是如何跳轉(zhuǎn)到某個(gè)系統(tǒng)中的向量表的?如下框圖展示了這一切:當(dāng)一個(gè)中斷到來(lái)后,中斷信號(hào)交給gic,gic會(huì)進(jìn)行中斷的識(shí)別、優(yōu)先級(jí)、affinity路由等,然后通過(guò)AXI stream將信號(hào)交給core(cpu internface),cpu interface負(fù)責(zé)標(biāo)記中斷是irq還是fiq,這就是中斷斷言了(assert了),然后就是中斷的路由規(guī)則,target到相應(yīng)的EL級(jí)別,然后再檢查Mask標(biāo)記位,然后該中斷就被taken了(即PE acknowledge了),接下來(lái)PE還會(huì)根據(jù)EL是否發(fā)生改變、SPELx使用的哪一個(gè)等信息來(lái)決定是跳轉(zhuǎn)到哪一組向量表 最后PE跳轉(zhuǎn)到相應(yīng)的VBARELx + xxx offset了。

審核編輯 :李倩
-
cpu
+關(guān)注
關(guān)注
68文章
11288瀏覽量
225242 -
Linux
+關(guān)注
關(guān)注
88文章
11772瀏覽量
219136 -
操作系統(tǒng)
+關(guān)注
關(guān)注
37文章
7405瀏覽量
129380
原文標(biāo)題:armv8-armv9中斷系列詳解-硬件基礎(chǔ)篇
文章出處:【微信號(hào):LinuxDev,微信公眾號(hào):Linux閱碼場(chǎng)】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
Freescale MC9S08SE8系列MCU深度解析
從“能用”到“懂原理”:ARMv8寄存器架構(gòu)深度拆解
ARMv8體系結(jié)構(gòu)入門(附流程圖+腦圖)
M6000-S下掛OLT閃斷問(wèn)題分析
Arm Flexible Access方案引入Armv9邊緣AI計(jì)算平臺(tái)
新唐科技NuMicro M253系列微控制器盤點(diǎn)
瑞薩RA系列MCU的外部引腳中斷詳解
脈沖編碼器TIM3中斷不生效是怎么回事?
優(yōu)比施UPS電源:為關(guān)鍵設(shè)備構(gòu)筑電力“零中斷”防線
STM32G474進(jìn)入Fault3中斷沒(méi)辦法設(shè)置成周期性觸發(fā)嗎?
AS32X601驅(qū)動(dòng)系列教程 PLIC_中斷應(yīng)用詳解
第十章 W55MH32中斷應(yīng)用概覽
armv8-armv9中斷系列詳解-硬件基礎(chǔ)篇
評(píng)論