鐵人賽
下圖列出目前 risc-v 所定義 major interrupt 的優先權高低
插曲一下,不知道有沒有人注意到,這邊居然有 13 號 ,這是之前介紹
mip
時,沒提到的,該 interrupt 主要是當 counter overflow 時,所發出的 interrupt,之後講到 perf 的時候還會再提~
下圖為 AIA 目前對所有 interrupt ID 進行的分類
可以觀察到 0~15 是由 Privelege Spec 所定義的,其中 13~15 為 local interrupt ,補充一下目前只定義到 13 號 ,14、15目前保留但預計規劃是給 local interrupt 所做使用。
從 16 號開始,便是 AIA 所定義的,可以發現 16~23為 local interrutp ,24~31 為自定義所使用,32~47為 local interrupt ,之後便是自定義所使用。
因此統整一下目前整個 interrupt 的優先權高低,可由下圖觀察
下圖為目前 risc-v 所定義的數字,但這不是最終辦本,因此還有可能改變
無論實現了甚麼 local interrupt mie/mieh
和 mip/miph
相對應的 bit 都要是可寫的,且 mideleg/midelegh
相對應的 bit 也要是可寫的。當發生 interrupt 時, mip/miph
皆要被舉起(設為1),然後保持該狀態,直到軟體把它清除。
只要滿足以下所有條件 interrupt 就會進到 M mode:
mstatus
的 MIE
bit 被舉起,或是當前特權模式低於 M modemip/miph
以及 mie/mieh
被舉起mideleg
存在,相對應的 bit 為 0當多個 interrupt 同時觸發時,會根據 interrupt 的優先順序決定,當然也是可以根據軟體做修改優先順序。
當 MXLEN = 32時,定義了16個暫存器,下面列出他們的 miselect
地址:
每個暫存器控制4個 interrupt 的優先權,每個 interrutp 8個 byte。對於範圍 0~15 的數字 k ,暫存器 ipropk 控制 interrupt k * 4 到 k*4+3 格式如下:
當 MXLEN = 64時,只存在偶數暫存器:
每個暫存器控制8個 interrupt 的優先權,對於 0~14 範圍內的偶數 k,暫存器 ipriok 控制 interrupt k4 到 k4+7 的優先權,格式如下:
當 MXLEN =64 且 miselect
是0x31 ~ 0x3f的奇數值時,嘗試 access mireg
會引起 illegal instruction exception。
有效暫存器 iprio0 ~ iprio15 統稱為 iprio array。 external interrupt 的優先權寬為 IPRIOLEN。
對於 APLIC 來說,IPRIOLEN 範圍在1~8;對於 IMSIC 來說,IPRIOLEN 範圍可能在6、7 或 8。當 IMSIC 實現 external interrupt ID 為 63 時,IPRIOLEN才可能為 6,當external interrupt ID為 127 時,IPRIOLEN 可能為 7,不管 external interrupt ID 數量為何 IPRIOLEN 都可以為8。
對於 interrupt number 來說,如果 mie/mieh
中相對應的 bit 只讀零,則 iprio array 中的 interrupt 優先順序也必須只讀零,machine level external interrupt 的優先順序也只讀零。除了這兩個限制之外,實現者可以選擇,哪些優先順序的欄位是可以設定的,哪些是只讀零的。如果 iprio array 中的所有 byte 皆只讀零,則只能幫 exterrnal interrupt 配置優先順序,而不能幫其他 interrupt 配置優先順序。
iprio array access 透過 miselect
以及 mireg
當 interrupt trap 到 M-mode 時會影響 interrupt 的優先順序,當 interrupt 在 array 中的優先順序為0時,其優先順序則為默認的順序。將 interrupt 的優先順序設定為p(p為非0),則該 interrupt 與 machine level exterrnal interrupt 具有相同優先順序。
假設 major interrupt 優先權比 machine level external 還高,則將其優先權降低。假設 major interrupt 優先權比 machine level external 還低,則將其優先權降調高。
如果系統使用 PLIC 或是 Duo-PLIC 與舊軟體向下相容,則重製後應將 machine level iprio array 初始化為0。
machine level CSR: mtopi
是 read-only,寬為MXLEN。
mtopi格式如下:
mtopi
的其他 bit 被保留或是讀取為0
除非 mip/miph
中有一 bit 舉起,且 mie/mieh
也舉起,否則 mtopi
的值為0。
當 pending bit 和 enabled bit 被舉起時,欄位IID (interrupt ID)為最高優先順序的 interrupt ID,欄位 IPRIO 表示其優先權。
如果 machine level iprio array 所有 byte 皆只讀0,則允許簡化 IPRIO 的實現,其中只要mtopi
不為0,IPRIO則為1。
否則,當 mtopi
不為0時,如果 interrupt 的優先順序在 1~255 之間,則 IPRIO 就是該數。如果 interrupt 的優先順序為0或大於255,則 IPRIO 設定不是0就是255,如下所示:
RISCV AIA 確保當 mtopi
的值不為0時,且當前為 m mode 並且mstatus中的MIE bit已設定,或是當前特權模式小於M mode,則將trap轉移到M mode。 trap不會導致mtopi的值發生改變。
以下程式碼顯示machine level trap如何讀取mtopi,以避免多餘的復原和保存暫存器,當在處理一個trap期間不會再出現interrupt,進行搶佔。
明天來介紹 supervisor level 的 interrupt,掰餔